鼠年的春节只有三个字'宅~宅~宅~',宅来无事想起之前碰到的一个JS题目,感觉还是蛮有趣的,放出来大家一起思考下~
首先我们说一下题目(需求来了,面对疾风吧~)
/**
* 请写出两种或两种以上实现方法满足: execute 对应的id按顺序打印
* PS: 尝试只修改start函数体
*
* 输出结果参考:
* id 0
* id 1
* id 2
* id 3
* id 4
*/
function start(id) {
execute(id).catch(console.error);
}
// 测试代码 (请勿更改):
for (let i = 0; i < 5; i++) {
start(i);
}
function sleep() {
const duration = Math.floor(Math.random() * 500);
return new Promise(resolve => setTimeout(resolve, duration));
}
function execute(id) {
return sleep().then(() => {
console.log("id", id);
});
}
看到这个题目大家可以思考30s,想一想怎么去解这道题目,有兴趣的可以直接拷贝题目到一个顺手的编辑器里尝试写一写,对于程序猿来说思考的过程还是很重要的
下面开始写答案了哦~ 当然了,只是我的解题方案,大家有什么更好的方案也希望可以在评论区不吝赐教,也可以扫码添加文末二维码在微信群进行交流。准备好了吗?Baby~
以下答案只会放start函数体的更改,毕竟我们的题干只要求更改start函数体
答案一
此方案可以实现需求,但是每次调用start函数,都会清除timer,导致只有所有的调用都push完才会真正执行execute函数,代码也不优雅,算是勉强可以实现功能
注意,本例子中的start函数体内this.x是可以替换为start.x的,这样做,可避免严格模式下this为undefined而导致的异常,在非严格模式下可避免污染全局变量
function start(id) {
if (!this.processList) this.processList = [];
this.processList.push({ id });
clearTimeout(this.t);
this.t = setTimeout(() => {
(async () => {
let target = this.processList.shift();
while (target) {
await execute(target.id);
target = this.processList.shift();
}
})();
}, 0);
}
作为一个有追求的FEer怎么可以仅仅停留在方案一呢,思考~~~
答案二
经过苦苦思索,终于打通任督二脉写出了个人认为最优雅的实现方案,这个方案不需要借助定时器,思路就是Promise的链式调用即then函数
function start(id) {
start.promises = !start.promises
? execute(id)
: start.promises.then(() => execute(id));
}
到此,解题告一段落,整个解题过程还是痛苦的,但是解题完毕还是蛮有成就感的~
对前端技术交流有兴趣的同学,可以微信扫码下面的关注公众号【见闻号】或者加入前端开发者微信群,方便大家交流前端技术
本文为原创文章,仅作个人存档所用,请勿随意转载。如确有转载需求,请在转载时务必带上原文链接!码字不易,多谢合作!