console.log(1); setTimeout(function () { console.log(2); new Promise(function (resolve, reject) { console.log(3); resolve(); console.log(4); }).then(function () { console.log(5); }); }); function fn() { console.log(6); setTimeout(function () { console.log(7); }, 50); } new Promise(function (resolve, reject) { console.log(8); resolve(); console.log(9); }).then(function () { console.log(10); }); fn(); console.log(11); // 以下代码需要在 node 环境中执行 process.nextTick(function () { console.log(12); }); setImmediate(function () { console.log(13); });
优先级
通过上面的介绍,我们就可以得出一个代码执行的优先级:
同步代码 > process.nextTick > Promise(微任务)> setTimeout(fn)、setInterval(fn)(宏任务)> setImmediate(宏任务)> setTimeout(fn, time)、setInterval(fn, time),其中time>0
综上,最终的输出顺序是:1 8 9 6 11 12 10 2 3 4 5 13 7
详细的解说:http://www.laixiangran.cn/2018/04/16/JavaScript%E4%B9%8BEvent%20Loop/
console.log(1); setTimeout(function() { new Promise(function(resolve) { console.log('promise in setTimeout1'); resolve(); }).then(function() { console.log('then in setTimeout1'); }) }, 10); new Promise(function(resolve) { console.log(3); for (var i = 100000; i > 0; i--) { i == 1 && resolve(); } console.log(4) }).then(function() { console.log(5); }); setTimeout(function() { console.log('setTimeout2'); }, 10); console.log(7); //1,3,4,7,5,promise in setTimeout1,then in setTimeout1,setTimeout2
- 可以发现,第二个setTimeout 的回调函数,
- 执行的比第一个setTimeout里面的promise.then()的回调要晚,
- 这是因为每次循环只执行一个宏任务,
- 但是却会执行所有待执行的微任务,
- 而第二个setTimeout在宏任务队列的位置在第一个setTimeout后面。