当前位置: 首页 > Web前端 > JavaScript

分别用es5和es6实现异步串行和异步并行

时间:2023-03-27 01:46:32 JavaScript

使用es5和es6分别实现异步串行和异步并行然后就可以调用下一个函数了线程视角】任务调用后,当前线程不会被挂起,不需要等待被唤醒也可以继续工作串口:【CPU视角】任务之间存在依赖关系,每个任务只能被一个任务执行CPU核并行:【CPU视角】任务之间没有依赖,多个任务由多个执行一个CPU核执行es5实现异步串行难点拆解:核心部分,如何实现串行?serial的本质是还原到函数的角度,即一个函数执行完后,再执行下一个函数;同步函数固然好,但是异步时,就要考虑使用回调来执行下一个函数。那么我们把问题转化为:执行完函数后回调如何执行?自然有两种解决方案:stack方法循环和递归done方法如何实现?done方法的本质是在所有任务串行执行完毕后,再执行done方法。不过需要注意的是,函数实体是先执行的,然后返回done方法对象让用户注册回调函数。显示代码函数log(x,cb){console.log(x)cb&&cb()}functionsleep(v,time,cb){setTimeout(()=>{console.log(v)cb&&cb()},time)}functionserialize(tasks){letdoneCb;functionnext(){letfn=tasks.shift()if(fn){fn(next)}else{doneCb&&doneCb()}}next();return{done:(cb)=>{if(cb){doneCb=cb;}}}}serialize([(cb)=>log(1,cb),(cb)=>log(2,cb),(cb)=>sleep(3,3000,cb),(cb)=>log(4,cb)]).done(()=>{console.log('done')})思路总结:使用next方法递归实现,执行完一个任务后执行下一个任务。留下一个思考问题,如果使用stack方式,如何实现,需要处理哪些细节问题?es6实现异步串行方案一:async/await难点分析:async/await最后会返回promise对象,那么如何实现返回done对象呢?只需要在里面实现一个async/await函数,外层直接返回done对象。done方法能不能像es5方法一样判断fn不存在就执行呢?不是,因为遇到await就跳出了异步处理,后面的函数还没有执行完,所以这时候是没办法拿到done回调的。函数日志(x,cb){控制台。log(x)}functionsleep(v,time){returnnewPromise((resolve)=>{setTimeout(()=>{console.log(v)resolve()},time)})}functionserialize(tasks){asyncfunctionconsume(){while(tasks.length){letfn=tasks.shift()if(fn){awaitfn()}}}consume();return{done:(cb)=>{if(cb){tasks.push(cb)}}}}serialize([(cb)=>log(1,cb),(cb)=>log(2,cb),(cb)=>sleep(3,3000,cb),(cb)=>log(4,cb)]).done(()=>{console.log('done')})选项2:Promise难点分析:如何巧妙的使用then方法实现序列化?如何考虑done方法?serialize([log(1),log(2),sleep(3),log(4)]).done(()=>{console.log('done')})//输出:1234donefunctionlog(x){return()=>console.log(x)}functionsleep(y){return()=>newPromise((resolve)=>{setTimeout(()=>{resolve(y)},0)})}函数isPromise(obj){returntypeofobj==='object'&&typeofobj.then==='function'}函数序列化(arr){letpromiseResolver=Promise.resolve()arr.forEach(item=>{letresultpromiseResolver=promiseResolver.then(()=>{//同步任务直接执行result=item();//异步任务直接返回,写回调执行consoleif(isPromise(result)){returnresult.then(x=>{console.log(x)})}})})return{done:(fn)=>{promiseResolver=promiseResolver.then(()=>{fn()});}}}es5实现异步并行难点分析:如何实现异步并行?实际上所有的任务都执行一次,当最新完成的任务完成时调用done方法。你怎么知道所有的任务都已经执行了?计算器/状态标记何时调用done方法?即计数器获取任务的数量并执行它们。所有任务的状态都标记为已完成,并已执行。parallel([(cb)=>log(1,cb),(cb)=>sleep(2,1000,cb),(cb)=>log(3,cb),(cb)=>sleep(4,2000,cb),(cb)=>log(5,cb)]).done(()=>{console.log('done')})//输出:13524done//其中done在2秒后执行*/functionlog(x,cb){console.log(x)cb&&cb()}functionsleep(v,time,cb){setTimeout(()=>{console.log(v)cb&&cb()},time)}functionparallel(tasks){letdoneCb;让计数=0;让tasksLength=tasks.length;functionisFinish(){console.log(count,tasksLength)if(count==tasksLength){doneCb&&doneCb()}}functiontaskCb(){count++;isFinish()}while(tasks.length){让fn=tasks.shift();如果(fn){fn(taskCb);}}return{done:(cb)=>{if(cb){doneCb=cb;}}}}parallel([(cb)=>log(1,cb),(cb)=>sleep(2,1000,cb),(cb)=>log(3,cb),(cb)=>雪橇ep(4,2000,cb),(cb)=>log(5,cb)]).done(()=>{console.log('done')})es6实现异常并运行functionlog(x){returnnewPromise((resolve)=>{console.log(x)resolve()})}functionsleep(v,time){returnnewPromise((resolve)=>{setTimeout(()=>{console.log(v)resolve()},time)})}functionparallel(tasks){letdoneCb;Promise.all(tasks).then(()=>{doneCb&&doneCb();})返回{done:(cb)=>{if(cb){doneCb=cb;}}}}parallel([log(1),sleep(2,1000),log(3),sleep(4,2000),log(5)]).done(()=>{console.log('done')})参考https://cloud.tencent.com/dev...https://segmentfault.com/a/11...