We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
对于这个概念,理解过多次才有点认知,本文理解尚浅,可查看后续文章加深
以前似乎并不知道有这个概念,(很害羞的说出这句话~),直到16年倒数第二天逛掘金时遇到这题:
setTimeout(function(){ console.log(4) }, 300) setTimeout(function(){ console.log(3) }, 200) for (var i=0; i<1000000; i++) { console.log(1) } setTimeout(function(){ console.log(2) }, 100)
看到这题的时候,凭借“习惯”的想到,for循环的时间会不会很长,超过100ms,那这答案不确定了。后面再想到js是单线程从上到下执行,那很自然想到结果是1 2 4 3
1 2 4 3
后面又看到一题,直接懵逼
(function test() { setTimeout(function() {console.log(4)}, 0); new Promise(function executor(resolve) { console.log(1); for( var i=0 ; i<10000 ; i++ ) { i == 9999 && resolve(); } console.log(2); }).then(function() { console.log(5); }); console.log(3); })()
看了题就发现其实知识还是无穷无尽的。好吧,废话说了这么多,进入正题~(以下内容仅属个人看法,有误之处希望批评指正)
js 只有一个main thread 主进程和call-stack(一个调用堆栈),所以在对一个调用堆栈中的task处理的时候,其他的都要等着。task等待被加入调用堆栈等待执行的时候,被放在task queue事件队列之中。 每当主线程完成一个任务的时候,他就会去调用堆栈中获取task执行。
而task分为:
script(整体代码),setTimeout, setInterval, setImmediate, I/O, UI rendering
process.nextTick, Promises, Object.observe, MutationObserver
二者的关系:
JavaScript引擎首先从macrotask queue中取出第一个任务,执行完毕后,将microtask queue中的所有任务取出,按顺序全部执行; 然后再从macrotask queue中取下一个,执行完毕后,再次将microtask queue中的全部取出; 循环往复,直到两个queue中的任务都取完。
【参考】Macrotask Queue和Microtask Quque
有了这些概念以后再来看上面第一题。
所以结果是1 3 4 2,关于2的打印顺序与for循环的时间有关,我们这里的for时间大于400ms,所以2才最后打印。
1 3 4 2
第二题是一个立即执行函数:
所以结果是1 2 3 5 4
1 2 3 5 4
【参考】从Promise来看JavaScript中的Event Loop、Tasks和Microtasks
最后再来一道题加深理解:
console.log('start') const interval = setInterval(() => { console.log('setInterval') }, 0) setTimeout(() => { console.log('setTimeout 1') Promise.resolve() .then(() => { console.log('promise 3') }) .then(() => { console.log('promise 4') }) .then(() => { setTimeout(() => { console.log('setTimeout 2') Promise.resolve() .then(() => { console.log('promise 5') }) .then(() => { console.log('promise 6') }) .then(() => { clearInterval(interval) }) }, 0) }) }, 0) Promise.resolve() .then(() => { console.log('promise 1') }) .then(() => { console.log('promise 2') })
题解: 我们将macrotask 和 microtask 看作是2个队列,不断的清空入栈执行。
所以打印顺序是:start, promise 1, promise 2, setInterval, setTimeout 1, promise 3, promise 4, setInterval, setTimeout 2, promise 5, promise 6
start, promise 1, promise 2, setInterval, setTimeout 1, promise 3, promise 4, setInterval, setTimeout 2, promise 5, promise 6
在一个事件循环的周期(cycle)中一个 (macro)task 应该从 macrotask 队列开始执行。当这个 macrotask 结束后,所有的 microtasks 将在同一个 cycle 中执行。在 microtasks 执行时还可以加入更多的 microtask,然后一个一个的执行,直到 microtask 队列清空。
【参考】 理解事件循环一(浅析) 理解事件循环二(macrotask和microtask) Javascript 单线程
The text was updated successfully, but these errors were encountered:
Firefox 、Safari 是可以这样讲通 较个真, Chrome 里面答案真的不完全是这样.
Sorry, something went wrong.
@pengVc 感谢提醒,刚执行多次发现确实偶尔会出现这种情况,performance分析,莫名其妙会执行2遍,chrome bug?
No branches or pull requests
以前似乎并不知道有这个概念,(很害羞的说出这句话~),直到16年倒数第二天逛掘金时遇到这题:
看到这题的时候,凭借“习惯”的想到,for循环的时间会不会很长,超过100ms,那这答案不确定了。后面再想到js是单线程从上到下执行,那很自然想到结果是
1 2 4 3
后面又看到一题,直接懵逼
看了题就发现其实知识还是无穷无尽的。好吧,废话说了这么多,进入正题~(以下内容仅属个人看法,有误之处希望批评指正)
基本概念
js 只有一个main thread 主进程和call-stack(一个调用堆栈),所以在对一个调用堆栈中的task处理的时候,其他的都要等着。task等待被加入调用堆栈等待执行的时候,被放在task queue事件队列之中。
每当主线程完成一个任务的时候,他就会去调用堆栈中获取task执行。
而task分为:
script(整体代码),setTimeout, setInterval, setImmediate, I/O, UI rendering
process.nextTick, Promises, Object.observe, MutationObserver
二者的关系:
【参考】Macrotask Queue和Microtask Quque
题目解答
有了这些概念以后再来看上面第一题。
所以结果是
1 3 4 2
,关于2的打印顺序与for循环的时间有关,我们这里的for时间大于400ms,所以2才最后打印。第二题是一个立即执行函数:
所以结果是
1 2 3 5 4
【参考】从Promise来看JavaScript中的Event Loop、Tasks和Microtasks
最后再来一道题加深理解:
题解:
我们将macrotask 和 microtask 看作是2个队列,不断的清空入栈执行。
所以打印顺序是:
start, promise 1, promise 2, setInterval, setTimeout 1, promise 3, promise 4, setInterval, setTimeout 2, promise 5, promise 6
【参考】
理解事件循环一(浅析)
理解事件循环二(macrotask和microtask)
Javascript 单线程
The text was updated successfully, but these errors were encountered: