使用JS实现图文混发

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 使用JS实现图文混发

前言


在我的开源项目中,很早之前实现了图文混输的功能,但是在解析消息时,解析到图片需要将其上传至服务器拿到图片地址进行特殊拼接,上传图片是异步,解析图片是同步,这就造成了文字消息已经发出去了,图片才开始上传,导致图片拼接失败。

本文就跟大家分享下我解决这个问题的实现思路以及过程,欢迎各位感兴趣的开发者阅读本文。


先跟大家展示下最终实现的效果:


640.gif


实现思路


正如开头所讲,上传图片是异步,处理文字消息是同步,那么我们想办法让上传图片执行完,拿到图片返回地址后再去执行后续的处理代码,这样就可以解决我们遇到的问题了。


所以,我们现在要做的就是等异步函数执行完再执行同步函数,于是,我想到了await,我们将上传图片的函数单独提取出来,让其返回一个Promise 对象,将发送消息的函数改为 async function,这样我们就可以使用await操作符等待图片上传函数执行完成返回图片地址,将其拼接后继续执行后面的同步代码,完美解决我们遇到的问题。


接下来,我们将上述思路进行整理,如下所示:


  • 提取上传图片函数,返回一个Promise对象
  • 将发送消息的函数改为异步async
  • 解析图片时使用await执行上传图片函数
  • 消息文本拼接上传图片函数返回的文件名


await只能用于promise用于等待一个Promise 对象,要使用await当前函数必须为async的异步函数。


实现过程


实现之前先跟大家看下我的消息内容是如何描述图片信息的,如下所示,我们会用//将图片信息包裹起来。


let msgTest = `你好,我是大白/1290219.jpeg?width=658&height=658/`;


提取上传图片函数


将上传图片的函数提取出来,返回一个promise,代码如下所示:


// 上传图片
uploadImage: function(formData: FormData) {
  return new Promise((resolve, reject) => {
    // 将图片上传至服务器
    this.$api.fileManageAPI
      .upload(formData)
      .then((res: responseDataType) => {
        // 文件上传失败
        if (!_.isEqual(res.code, 0)) {
          alert(res.msg);
          reject({ msg: res.msg, code: -1 });
        }
        // 图片名
        let msgImgName = "";
        const imgSrc = `${base.lkBaseURL}/uploads/chatImg/${res.fileName}`;
        // 获取图片大小
        const img = new Image();
        let imgWidth = 0;
        let imgHeight = 0;
        // 赋值图片地址
        img.src = imgSrc;
        // 判断图片是否有缓存
        if (img.complete) {
          imgWidth = img.width;
          imgHeight = img.height;
          msgImgName = `/${res.fileName}?width:${imgWidth}&height:${imgHeight}/`;
          resolve({ msg: msgImgName, code: 0 });
        } else {
          img.onload = () => {
            imgWidth = img.width;
            imgHeight = img.height;
            msgImgName = `/${res.fileName}?width=${imgWidth}&height=${imgHeight}/`;
            resolve({ msg: msgImgName, code: 0 });
          };
        }
      });
  });
}


修改发送消息函数为异步


这一步很简单,只需要在原函数声明时添加async即可,如下所示:


// 消息发送
sendMessage: async function(event: KeyboardEvent) {
   // 其他代码省略,可移步至github查看      
}


对消息发送函数代码感兴趣的开发者请移步:sendMessage


使用await执行图片上传函数


我们在sendMessage函数内部,解析到图片时,调用上传函数上传时在其函数前面加上await,用一个变量接收它,就能拿到我们promise中resolve所返回的数据,代码如下所示。


// 上传图片获取图片地址
const res: { code: number; msg: string } = await this.uploadImage(
   formData
);


完整代码在sendMessage中,感兴趣的开发者欢迎移步。


拼接图片信息至消息文本中


上述await会等图片上传函数执行完,将resolve返回的值复制给res,此时我们只需要从res中取值进行拼接即可,代码如下:


// 将图片地址拼接至待发送消息中
msgText += res.msg;


完整代码在sendMessage中,感兴趣的开发者欢迎移步。


实现效果


完成上述步骤后,我们的问题解决了,效果正如文章开头所看到的那样,图文混发的效果QQ是实现了的,但是微信就没实现,不晓得原因,可能正如张小龙所说的:每天都有人在教我做产品😂


文中代码地址:message-display.vue


在线体验地址:chat-system


写在最后


  • 公众号无法外链,如果文中有链接,可点击下方阅读原文查看😊
相关文章
|
JavaScript 前端开发
javascript深拷贝和浅拷贝以及实现方法(推荐)
javascript深拷贝和浅拷贝以及实现方法(推荐)
609 0
javascript深拷贝和浅拷贝以及实现方法(推荐)
|
JavaScript 算法 前端开发
【前端算法】JS实现数字千分位格式化
JS实现数字千分位格式化的几种思路,以及它们之间的性能比较
358 1
|
存储 前端开发 算法
一行代码解决LeetCode实现 strStr()使用JavaScript解题|前端学算法
一行代码解决LeetCode实现 strStr()使用JavaScript解题|前端学算法
177 0
一行代码解决LeetCode实现 strStr()使用JavaScript解题|前端学算法
|
存储 机器学习/深度学习 JavaScript
JS 你最少用几行代码实现深拷贝?
JS 你最少用几行代码实现深拷贝?
JS 你最少用几行代码实现深拷贝?
|
JavaScript 前端开发 算法
JavaScript实现一段时间之后关闭广告
简介:通过JavaScript实现在一段时间之后,广告消失。
140 0
JavaScript实现一段时间之后关闭广告
|
JavaScript 前端开发 算法
JS实现鼠标悬停变色
本文实现的是利用JS实现当鼠标悬停在表格上的时候,表格发生变色。 CSS渲染 JS逻辑 `
226 0
JS实现鼠标悬停变色
|
JavaScript 前端开发 数据安全/隐私保护
JS实现关闭图片窗口
通过事件的绑定来实现,关闭二维码的效果。
165 0
JS实现关闭图片窗口
|
前端开发 JavaScript Windows
js实现body背景图自动扩缩 光靠css几乎无法实现这样的效果
js实现body背景图自动扩缩 光靠css几乎无法实现这样的效果
208 0
js实现body背景图自动扩缩 光靠css几乎无法实现这样的效果
|
存储 JavaScript
js实现多选、全选、反选、取消选择(篇一)
js实现多选、全选、反选、取消选择(篇一)
409 0
|
JavaScript 前端开发
利用JavaScript实现二级联动
利用JavaScript实现二级联动 要实现JavaScript二级联动效果,首先要确定需要哪些技术: 二维数组 for in循环 new Option(text,value,true,true) add(option,null) onchange() 表单事件 HTML代码: <!-- <input type="text" id="text"> --> 请选择省份: <select name="" id="provinces"> <!-- <option value="江苏省">江苏省</option>