前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用JS实现图文混发

使用JS实现图文混发

作者头像
神奇的程序员
发布2022-04-10 09:30:29
1.6K1
发布2022-04-10 09:30:29
举报

前言

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

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

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

实现思路

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

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

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

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

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

实现过程

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

代码语言:javascript
复制
let msgTest = `你好,我是大白/1290219.jpeg?width=658&height=658/`;

提取上传图片函数

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

代码语言:javascript
复制
// 上传图片
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即可,如下所示:

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

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

使用await执行图片上传函数

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

代码语言:javascript
复制
 // 上传图片获取图片地址
const res: { code: number; msg: string } = await this.uploadImage(
   formData
);

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

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

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

代码语言:javascript
复制
// 将图片地址拼接至待发送消息中
msgText += res.msg;

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

实现效果

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

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

在线体验地址:chat-system

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-12-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 神奇的程序员 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 实现思路
  • 实现过程
    • 提取上传图片函数
      • 修改发送消息函数为异步
        • 使用await执行图片上传函数
          • 拼接图片信息至消息文本中
          • 实现效果
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档