前端异步加载多个分包数据的处理

前端异步加载多个分包数据的处理以及单线程与多线程对比

使用场景

前端需要加载一些分包的数据,最终拼成一个完整数据包时,需要考虑回包的顺序以及最后一个回包收到的事件通知。最容易想到的方式是先分配好每个数据包的位置,每次收到数据包时,检查数据包缓存是否排满,如果排满就使用发布订阅模式通知事件。

最佳实现方式

直接切入正题,走过了几条弯路以后才发现Promise.all方法才是最合适的解决方式。

//单线程
async function mainLoad() { 
    let arr = modelObj.bagInfo.body.map((v) => {
    	//这里可以是任何promise封装过的异步函数
        return ajaxGet( v ,"arraybuffer")
    })
    modelObj.vertex = await Promise.all(arr)
}

没错,就是这么简单,Promise.all会根据arr参数里promise对象的顺序去返回相同顺序的数据包。有类似需求的同学们,请认准Promise.all。

单线程加载与多线程加载的对比

如果使用多线程分包加载数据会不会快呢?
h5标准的worker线程也出来很多年了,如果只是纯前端开发,基本用不到。写个东西试试,用数据说话。

//多线程
async function workerLoad() {  
    let arr = modelObj.bagInfo.body.map((v,i) => {
        return spawnWorker(i)
    })
    modelObj.vertex = await Promise.all(arr)
}

// 生成多线程
function spawnWorker(i) {
    return new Promise((resolve, reject) => {
        let worker = new Worker('./worker.js', { name: i })
        worker.postMessage(modelObj.bagInfo.body[i])
        worker.onmessage = function (event) {
            resolve(event.data.res)
        }
    })
}

worker.js里的代码就是个ajax请求分包数据,收到后通知主线程,注意worker线程有一些内置对象是获取不到的,所以它能干的事情有限。
分5个数据包加载,分大包和小包,下面是各类情况下的结果。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
多线程加载大包或小包都要更慢???
看看下面的waterfall图就知道了,多线程还要多调用5个worker去生成ajax请求,线程之间还要有开销,所以肯定就慢了。
多线程
在这里插入图片描述
观察每一个请求发送的时间,单线程因为异步的关系,与多线程一样,几乎都是同时发送的。
查询有关浏览器事件循环模型相关资料,ajax请求本来就是启用其他线程去完成的,所以用worker纯属多此一举。
难道worker线程在前端就是鸡肋么?
当然不是,在webGL领域以及前端人工智能领域,把一些大计算量的工作放在worker去处理才能充分利用多核cpu,做做页面的话好像确实用不到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值