console.log(1);
setTimeout(function(){
console.log(2);
}, 0);
Promise.resolve().then(function(){
console.log(3);
}).then(function(){
console.log(4);
});
console.log(5);
结果:1,5,3,4,2
javascript是单线程的,就是说主线程拥有一个执行栈,他会将scrpit里面的内容作为一个task依次推入栈中,等待浏览器的执行。
当遇到异步函数时候,会先将该函数入栈,所有主线程函数运行完毕后再将异步函数出栈,直到所有的异步函数执行完毕即可,
setTimeout和Promise都是异步操作,所以他们需要等待主线程函数运行完毕,才会执行他们。由此我们知道浏览器会先输出1,5。
task任务,分为macrotasks和microtasks,
macrotasks: setTimeout, setInterval, setImmediate, I/O, UI rendering
microtasks: process.nextTick, Promise, MutationObserver
所以我们知道上述的setTimeout是'宏任务',Promise是‘微任务’,promise中的then方法的函数会被推入到microtasks队列中,而setTimeout函数会被推入到macrotasks。
任务队列中,在每一次事件循环中,macrotask只会提取一个执行,而microtask会一直提取,直到microsoft队列为空为止。
也就是说如果某个microtask任务被推入到执行中,那么当主线程任务执行完成后,会循环调用该队列任务中的下一个任务来执行,直到该任务队列到最后一个任务为止。而事件循环每次只会入栈一个macrotask,主线程执行完成该任务后又会检查microtasks队列并完成里面的所有任务后再执行macrotask的任务。
所以此时会先输出3,4再输出2.