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
推荐阅读 浏览器与Node的事件循环(Event Loop)有何区别?,讲解的十分清楚,完全解答了我的疑问。
在前端面试中经常会遇到代码执行顺序的问题,搞清楚异步与事件循环的机制,可以对此类问题一通百通。
众所周知“JavaScript是单线程的”。JavaScript只有一个主线程,负责解释和和执行JavaScript代码。
JavaScript主线程会按顺序去执行执行环境栈内的代码。当遇到耗时较长的任务时就会产生阻塞,当遇到死循环时会直接卡死,无法继续执行。
JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?所以,为了避免复杂性,从一诞生,JavaScript就是单线程。1
由于CPU执行速度很快,IO操作较慢。所有JavaScript设计为对于IO操作或计时任务都交由浏览器的web APIs或 node的C/C++ APIs去处理。等到处理完毕后再交到主线程去处理后续任务。
通常来说在编码过程中常常需要在异步操作处理完成后去执行对应任务。JavaScript会在异步操作完成后将对应的任务放到任务队列里面。等到主线程空闲时再去执行。
任务队列分为macrotasks和microtasks两种。
事件循环决定了JavaScript的执行顺序。 事件循环的顺序为
process.nextTick(function() { console.log(111) process.nextTick(function() { console.log(222) }) }) setImmediate(function () { console.log(333) }) // -> 111 222 333
setImmediate 和 setTimeout(function() {}, 0)很类似。 当这两者在非异步回调函数的执行环境内执行时,其执行先后顺序不确定。 在异步回调函数的执行环境内执行时setImmediate总会先于setTimeout(function() {}, 0)执行。
setImmediate(function () { console.log(111) }) setTimeout(function () { console.log(222) }) // 执行顺序不确定,结果可能是111 222或222 111 setTimeout(function test () { setImmediate(function () { console.log(111) }) setTimeout(function () { console.log(222) }) }, 0) // 执行顺序确定,总是 111 222
通过Javascript代码更新后的UI渲染会在microtasks之后,macrotasks之前进行。 3
<div id="div"> begin </div> <script> div.onclick = function () { div.innerHTML = 'end'; setTimeout(function() { alert(' ui 已经渲染完毕 '); console.log('timeout'); }, 0); new Promise(function(resolve) { console.log('promise1'); for (var i = 0; i < 1000; i++) { i == 99 && resolve(); } console.log('promise2'); }).then(function() { console.log('then1'); alert(' ui 开始渲染 '); }); console.log('global'); } // 执行顺序为 promise1, promise2, global, then1, ui 开始渲染, div内文字变为end, ui 已经渲染完毕, timeout </script>
经过多天的查询资料,基本搞清楚了事件循环的执行步骤,彻底掌握了这些异步代码的执行顺序问题。
但是在一些细节上仍留有疑惑,如process.nextTick的回调函数是先放入任务队列等待执行还是直接放入执行环境栈直接执行。关于setImmediate和setTimeout(function() {}, 0)执行顺序不确定的原因也未找到较好的解释。等以后找到资料具体理解之后再做补充。
下篇文章分析一下Promise,看看这个最初由社区实现的功能代码是如何写的。
[1] JavaScript 运行机制详解:再谈Event Loop [2] 理解异步JavaScript-事件循环 [3] Javascript事件循环机制以及渲染引擎何时渲染UI
The text was updated successfully, but these errors were encountered:
No branches or pull requests
前言
推荐阅读 浏览器与Node的事件循环(Event Loop)有何区别?,讲解的十分清楚,完全解答了我的疑问。
在前端面试中经常会遇到代码执行顺序的问题,搞清楚异步与事件循环的机制,可以对此类问题一通百通。
一、术语
1.1 同步 synchronous
众所周知“JavaScript是单线程的”。JavaScript只有一个主线程,负责解释和和执行JavaScript代码。
JavaScript主线程会按顺序去执行执行环境栈内的代码。当遇到耗时较长的任务时就会产生阻塞,当遇到死循环时会直接卡死,无法继续执行。
JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?所以,为了避免复杂性,从一诞生,JavaScript就是单线程。1
1.2 异步 asynchronous
由于CPU执行速度很快,IO操作较慢。所有JavaScript设计为对于IO操作或计时任务都交由浏览器的web APIs或 node的C/C++ APIs去处理。等到处理完毕后再交到主线程去处理后续任务。
1.3 任务队列 task queue
通常来说在编码过程中常常需要在异步操作处理完成后去执行对应任务。JavaScript会在异步操作完成后将对应的任务放到任务队列里面。等到主线程空闲时再去执行。
任务队列分为macrotasks和microtasks两种。
macrotasks
microtasks
1.4 事件循环
事件循环决定了JavaScript的执行顺序。
事件循环的顺序为
二、 特殊情况
2.1 process.nextTick
2.2 setImmediate
setImmediate 和 setTimeout(function() {}, 0)很类似。
当这两者在非异步回调函数的执行环境内执行时,其执行先后顺序不确定。 在异步回调函数的执行环境内执行时setImmediate总会先于setTimeout(function() {}, 0)执行。
2.3 UI渲染时机
通过Javascript代码更新后的UI渲染会在microtasks之后,macrotasks之前进行。 3
三、 总结
经过多天的查询资料,基本搞清楚了事件循环的执行步骤,彻底掌握了这些异步代码的执行顺序问题。
但是在一些细节上仍留有疑惑,如process.nextTick的回调函数是先放入任务队列等待执行还是直接放入执行环境栈直接执行。关于setImmediate和setTimeout(function() {}, 0)执行顺序不确定的原因也未找到较好的解释。等以后找到资料具体理解之后再做补充。
下篇文章分析一下Promise,看看这个最初由社区实现的功能代码是如何写的。
四、 参考
[1] JavaScript 运行机制详解:再谈Event Loop
[2] 理解异步JavaScript-事件循环
[3] Javascript事件循环机制以及渲染引擎何时渲染UI
The text was updated successfully, but these errors were encountered: