下面这这道题有助于我们去理解
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
console.log('script end');
以上结果输出是什么,答案是
image.png
你想到了吗?
先简单介绍几个概念。
单线程(single thread)
JS的本质核心就是单线程,这也就意味着所有的任务都得排队,前面的必须处理好,后面的才执行
执行栈(execution context stack)
执行栈也称为调用栈,在主线程上执行,形成一个执行栈
任务队列(queues)
任务分为同步任务
和异步任务
,只有在主线程上面执行的任务叫同步任务,即是前一个执行完毕后后面一个才执行。而异步任务不会进入主线程,它会被加入到任务队列
当中,只有任务队列通知主线程,某个异步的任务才开始执行,异步任务分为宏任务
和微任务
宏任务和微任务(Task、MicroTask)
宏任务
setTimeout、 setInterval 、 setImmediate、Dom、Ajax....
微任务
promise、asyc/await
微任务队列的执行顺序先于宏任务队列,这样就很好解释开文提到的那段代码的结果
console.log('script start');
和 console.log('script end');
都是同步的。promise
和setTimout
是异步的,而promise
是微任务,setTimeout
是宏任务,而微任务的执行顺序先于宏任务
一图胜前言。 很容易看出调用栈、宏观任务队列、微观任务队列
image.png
事件循环(Event Loop)
主线程从任务队列
中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)
定时器
setTimeout(function(){console.log(1);}, 0);
console.log(2);
这样的结果答案总是2、1
,这是因为setTimeou
t被加入任务队列
当中去,它必须等到同步任务和任务队列中的现有的是件都处理完,才去执行
网友评论