发一个自己的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