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

进阶应用题考你对Promise的熟悉度

时间:2023-03-28 01:16:37 HTML

微信搜索【GreatMovetotheWorld】,第一时间为大家分享前端行业动态、学习路径等。本文已收录到GitHubhttps://github.com/qq449245884/xiaozhi,里面有完整的测试站点、资料和我的一线厂商访谈系列文章。这篇文章应该早在两年前就写好了,因为是某知名Udxxx网课面试的面试题,现在只能凭着弱记回忆了。想说进阶题是因为一开始我以为自己看懂了Promise,但是遇到这种应用题还是被KO了。接触过Promise的人可能觉得没什么难的,就是处理异步async。varp=num=>newPromise((resolve,reject)=>{if(num<=2){setTimeout(resolve('Success!'),Math.random()*1000);return;}reject('失败!')});p(1).then(res=>{console.log(res)}).catch(error=>{console.log(error)});//“成功!”但除了比较常见的fetchAPI,其实还有很多高级的应用!下一道题是要考大家对Promise的熟悉程度,因为一开始真的不知道怎么解...来看题吧。一共有10个任务。一个调用最多可以调用3个,并且完成每个任务所需的时间都不同。请使用下面提供的模板,编写完成这10项任务的方法。/***@return{promise}*编写一个函数来执行任务*/functiontask(){}classhandleTask{constructor(maxCount){this.maxCount=maxCount;this.pendingTask=[];this.completed=0;}run(tasks){}}根据标题和提供的函数推断可能需要哪些变量:totalTask??:number=10→totalnumberoftasksmaxTask:number=3→maximumnumberoftaskpendingTask:[number]=[promise,promise...]→waitingtobeexecutedtaskcompleted:number→TrackhassuccessedseveralTasks写一个promise任务还算简单,/***@return{promise}*写一个函数来执行任务*/functiontask(){returnnewPromise((resolve,reject)=>{console.log('running')setTimeout(resolve(),Math.random()*1000)//每个任务需要的时间不同,所以这里使用random}).then(()=>{console.log('done')}).catch(()=>{console.log('error')})}但是写run()方法我完全卡住:不知道怎么一次执行3次,是跑3个任务吗?那么如何执行其他任务直到执行完成呢?伯爵总觉得会,但不知道怎么解决。其实需要一个很重要的东西count来计算你当前正在执行的任务数→计算当前正在执行的任务Task,如果count<3,task()就会被执行,所以3个Task会先执行。当其中一个任务做完后,计数会-1,然后继续做下一个任务run(tasks){if(this.count{this.count--;})}}pendingTask还有一个重要的点就是pendingTask用来存放待处理的任务,所以会是[4,5,6,7,8,9,10]开头,当[1,2,3]其中一个任务先处理完,就会抢到任务4继续处理,pendingTask也会变成[5,6,7,8,9,10]如下图所示:run(tasks){if(this.count{this.count--;this.pendingTask.shift()})}else{this.pendingTask.push(tasks);}}classhandleTask{constructor(maxCount){this.maxCount=maxCount;//3this.count=0;this.pendingTask=[];this.completed=0;}run(tasks){if(this.count{this.count--;this.completed++;this.pendingTask.shift(0);console.log('completed:',this.completed)})}else{this.pendingTask.push(任务);}}}functiontask(){//...缩写}letmyTask=newhandleTask(3);for(leti=0;i<10;i++){myTask.run(task);}有问题:总共完成了3个任务但是,最后发现completed只等于3,也就是说只成功完成了3个任务!一定有问题。解决这个问题是因为myTask.run(task);会瞬间运行十次(不管任务是否完成),pendingTask最初会是[4,5,6,7,8,9,10],然后因为if(this.count{this.count--;this.pendingTask.shift(0);})}只有[1,2,3]会遇到if中的run任务,pendingTask会是[7,8,9,10],但实际上[4,5,6]还没有执行run:为了继续执行剩下的任务,你应该改变this.pendingTask.shift(0);到if(this.pendingTask.length>0)this.run(this.pendingTask.shift())这个时候就比较考验JS的基本功了。如果this.pendingTask是[4,5,6,7,8,9,10],那么this.pendingTask.shift()会返回4;this.pendingTask然后改成[5,6,7,8,9,10],也就是继续把任务4扔进run,这样才能完成所有任务。代码部署后可能存在的bug,无法实时获知。事后为了解决这些bug,花费了大量的时间在日志调试上。顺便推荐一个好用的bug监控工具Fundebug。原文:https://medium.com/starbugs/%...交流有梦想,有干货,微信搜索【大招天下】关注这位大清早还在洗碗的洗碗小智。本文已收录到GitHubhttps://github.com/qq449245884/xiaozhi,里面有完整的测试站点、资料和我的一线厂商访谈系列文章。