作者: HannahLin
起源:medium
有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。
这一篇应该早在两年前就要写了,因为是当初面试某间出名的 Udxxx 线上课程的面试题,当初只能用我单薄的记忆回顾一下。要说进阶题是因为当初我自认为对 Promise 算理解,但遇到这种应用题还是被 KO。
有碰过 Promise 的人可能会感觉也没什么难的,就是解决非同步 async
。
var p = num => new Promise((resolve, reject) => { if(num <= 2) { setTimeout(resolve('Success!'), Math.random()*1000); return; } reject('Failure!') });p(1) .then(res => { console.log(res)}) .catch( error => { console.log(error)}); // "Success!"
但除了比拟常见的 fetch API,其实还有很多进阶利用呢!接下来这题就要考考大家对 Promise 的熟度,因为当初的我是真的齐全不晓得怎麽解啊…
来看题目吧
总共 10 个 tasks 一次 call 最多 3 个,每个 task 须要实现的工夫都不同。
请应用以下提供的范本,写出能实现这 10 个工作的办法。
/** * @return { promise } * 写一个执行 task 的 function */function task(){}class handleTask{ constructor(maxCount){ this.maxCount = maxCount; this.pendingTask = []; this.completed = 0; } run(tasks){}}
根据题目与提供的函数先推断可能须要哪些变量:
totalTask: number = 10
→ 总共几个 taskmaxTask: number = 3
→ 一次最多执行几个 taskpendingTask: [number] = [promise, promise...]
→ 期待被执行的 taskcompleted:number → Track
胜利了几个 Tasks
写一个 promise 的 task 还算简略,
/** * @return { promise } * 写一个执行 task 的 function */function task(){ return new Promise((resolve, reject) => { console.log('running') setTimeout(resolve(), Math.random()*1000) // 每个 task 所需工夫不同,所以这边用 random }).then(() => { console.log('done') }).catch(() => { console.log('error') })}
但要写 run()
这个 method 时我齐全卡住:
- 不晓得怎麽一次执行三次,是 run 3 次 task 吗?
- 那执行完要怎麽在执行别的 task 直到执行完 ?
count
总感觉会但又不晓得怎麽解,其实须要一个很重要的货色 count
,来计算你当初到底在执行哪一个 task
count
→计算当初正在执行的 Task,若 count < 3
就会执行 task()
,所以一开始会先执行 3 个 Tasks。
当其中一个 task 做完, count
就会 -1
,而后持续做下一个 task
run(tasks){ if(this.count < this.maxCount){ this.count ++; tasks().then(() => { this.count --; }) } }
pendingTask
另一个重点就是 pendingTask
拿来存待处理的工作,所以一开始会是 [4,5,6,7,8,9,10]
,当 [1,2,3]
其中一个 task 先解决完就会抓 task 4
持续解决,pendingTask
也会变 [5,6,7,8,9,10]
如下图:
run(tasks){ if(this.count < this.maxCount){ this.count ++; tasks().then(() => { this.count --; this.pendingTask.shift() }) } else{ this.pendingTask.push(tasks); }}
class handleTask{ constructor(maxCount){ this.maxCount = maxCount; // 3 this.count = 0; this.pendingTask = []; this.completed = 0; } run(tasks){ if(this.count < this.maxCount){ this.count ++; tasks().then(() => { this.count --; this.completed ++; this.pendingTask.shift(0); console.log('completed: ', this.completed) }) } else{ this.pendingTask.push(tasks); } }}function task () { //... 略}let myTask = new handleTask(3);for(let i=0; i< 10; i++){ myTask.run(task);}
呈现问题: 总共才实现 3 个工作
But, 发现 completed
最初才等于 3 而已,代表只胜利实现 3 个 tasks!肯定是哪裡出问题了啊。
解決
这是因为 myTask.run(task)
; 会一瞬间跑十次 (不论 task 有没有做完), pendingTask
一开始会是 [4,5,6,7,8,9,10] ,而后因为
if(this.count < this.maxCount){ this.count ++; // 前三个 task 会陆续做完 tasks().then(() => { this.count --; this.pendingTask.shift(0); })}
真正只有 [1, 2, 3]
会跑进 if
裡面 run task
,而 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,花了大量的工夫进行log 调试,这边顺便给大家举荐一个好用的BUG监控工具 Fundebug。
原文:
https://medium.com/starbugs/%...
交换
有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq44924588... 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。