setTimeout(() => {
  console.log(1)
})

new Promise((resolve, reject) => {
  console.log(2)
  resolve()
}).then(() => console.log(3))
console.log(4)
// 2 4 3 1
  • setTimeout是宏任务,先丢到宏任务队列
  • Promise内部是同步的 所以先打印2,.then是微任务, 丢进微任务事件对列中
  • 打印4
  • 执行微任务也及时.then中的,打印3
  • 最后执行宏任务,打印1
  1. Javascript是单线程的,所有的同步任务都会在主线程中执行。
  2. 当主线程中的任务,都执行完之后,系统会 “依次” 读取任务队列里的事件。与之相对应的异步任务进入主线程,开始执行。
  3. 异步任务之间,会存在差异,所以它们执行的优先级也会有区别。大致分为 微任务(micro task,如:Promise、MutaionObserver等)和宏任务(macro task,如:setTimeout、setInterval、I/O等)。
  4. Promise 执行器中的代码会被同步调用,但是回调.then是基于微任务的
  5. 微任务优先宏任务
 console.log('1');//
        setTimeout(function () {
            console.log('2');//
            new Promise(function (resolve) {
                console.log('3');//
                resolve();
            }).then(function () {
                console.log('4');//
            })
        }, 0);
        new Promise(function (resolve) {
            console.log('5');//
            resolve();
        }).then(function () {
            console.log('6');//
        });
        setTimeout(function () {
            console.log('7');//
            new Promise(function (resolve) {
                console.log('8');//
                resolve();
            }).then(function () {
                console.log('9');//
            });
        })
//1 5 6 2 3 4 7 8 9
  • script标签内属于一个宏任务,当遇到微任务,会先执行完微任务,然后再执行下一个宏任务,所以setTimeOut就落后.then执行

《你不知道的JAVASCRIPT》第155也有写:这里使用setTimeOut(..0)进行异步调度,基本上它的意思就是"把这个函数插入到当前时间循环队列的末尾"


爬。