发一个自己的solution
class U {
#taskQueue = []
#next() {
const fn = this.#taskQueue.shift();
if(fn) fn();
}
#newTask(fn) {
this.#taskQueue.push(() => { fn(); } );
if(this.#taskQueue.length === 1) {
setTimeout(this.#next.bind(this), 0);
}
return this;
}
console(...args) {
this.#newTask(() => { console.log(...args); this.#next(); })
return this;
}
setTimeout(timeout) {
this.#newTask(() => { setTimeout(this.#next.bind(this), timeout); })
return this;
}
}
const u = new U();
u.console('a').setTimeout(3000).console('b').setTimeout(3000).console('c');
用了setTimeout(fn, 0)
的技巧,将任务链的执行延迟到下个事件循环周期。
好处是不依赖promise了,坏处是执行延迟到下个事件循环周期,也就是这个代码:
u.console('a').setTimeout(3000).console('b').setTimeout(3000).console('c');
console.log("this message should appear after 'a'")
的输出是
this message should appear after 'a'
a
b
c
可能会导致一些运行顺序相关的坑
另一个不如promise的,因用的是宏任务队列,宏任务过多时可能会延迟比较久开始执行
Q:
1.setTimeout(this.#next.bind(this), 0)
的作用和效果是什么?改成this.#next()
为什么不行?
2.使用setTimeout(fn ,0)
和使用 Promise 原理上的差异在哪里?
3.实现custom、customAsync