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
什么是单线程
主程序只有一个线程,即同一时间片断内其只能执行单个任务。
为什么选择单线程?
JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。
单线程意味着什么?
单线程就意味着,所有任务都需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就需要一直等着。这就会导致IO操作(耗时但cpu闲置)时造成性能浪费的问题。
IO操作(耗时但cpu闲置)
如何解决单线程带来的性能问题?
答案是异步!主线程完全可以不管IO操作,暂时挂起处于等待中的任务,先运行排在后面的任务。等到IO操作返回了结果,再回过头,把挂起的任务继续执行下去。于是,所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。
注: 当主线程阻塞时,任务队列仍然是能够被推入任务的
JavaScript 内存模型
讲事件循环之前,先看一张下网上看到的 JavaScript 内存模型,相信看完这个会对事件循环机制有一种豁然开朗的感觉。
JavaScript 代码执行机制:
Event Loop
现在我们来聊事件循环。事件循环顾名思义它就是一个循环,主线程会不断循环执行上面的第三步,其基本的代码逻辑如下所示:
while (queue.waitForMessage()) { queue.processNextMessage(); }
常见异步任务进入任务队列时机
事件循环机制图解:
MacroTask(Task) setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI rendering
MicroTask(在ES2015规范中称为Job) process.nextTick, Promise, Object.observe, MutationObserver
规范:
注: event loop的每个turn,是由浏览器决定先执行哪个task queue。这允许浏览器为不同的task source设置不同的优先级,比如为用户交互设置更高优先级来使用户感觉流畅。
function ELoop() { // 当前任务 let p = new Promise((resolve, reject)=>{ console.log("current Task") resolve(); }); let nextP; setTimeout(()=>{ console.log("MacroTask_1"); nextP.then(()=>{ // 第一次执行时,这段代码并没有执行到。 console.log("MicroTask_promise_1"); //第一个MicroTask }) console.log("MacroTask_1 end") }, 0) // 第一个 MacroTask setTimeout(()=>{ console.log("MacroTask_2"); console.log("MacroTask_2 end") }, 0)// 第二个MacroTask nextP = p.then(()=>{ console.log("MicroTask_promise_2"); //第一个MicroTask console.log(1) }).then(()=>{ console.log("MicroTask_promise_3"); // 第二个MicroTask console.log(1) }) console.log("current Task end") } ELoop(); /**输出结果: current Task MicroTask_promise_2 MicroTask_promise_3 MacroTask_1 MicroTask_promise_1 MacroTask_2 **/
参考文献:
从Promise来看JavaScript中的Event Loop、Tasks和Microtasks
JavaScript Event Loop 机制详解与 Vue.js 中实践应用
JavaScript 运行机制详解:再谈Event Loop
The text was updated successfully, but these errors were encountered:
No branches or pull requests
JavaScript 是单线程单并发语言
什么是单线程
主程序只有一个线程,即同一时间片断内其只能执行单个任务。
为什么选择单线程?
JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。
单线程意味着什么?
单线程就意味着,所有任务都需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就需要一直等着。这就会导致
IO操作(耗时但cpu闲置)
时造成性能浪费的问题。如何解决单线程带来的性能问题?
答案是异步!主线程完全可以不管IO操作,暂时挂起处于等待中的任务,先运行排在后面的任务。等到IO操作返回了结果,再回过头,把挂起的任务继续执行下去。于是,所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。
注: 当主线程阻塞时,任务队列仍然是能够被推入任务的
事件循环(Event Loop)
JavaScript 内存模型
讲事件循环之前,先看一张下网上看到的 JavaScript 内存模型,相信看完这个会对事件循环机制有一种豁然开朗的感觉。
JavaScript 代码执行机制:
Event Loop
现在我们来聊事件循环。事件循环顾名思义它就是一个循环,主线程会不断循环执行上面的第三步,其基本的代码逻辑如下所示:
常见异步任务进入任务队列时机
事件循环机制图解:
任务
MacroTask(Task)
setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI rendering
MicroTask(在ES2015规范中称为Job)
process.nextTick, Promise, Object.observe, MutationObserver
规范:
注: event loop的每个turn,是由浏览器决定先执行哪个task queue。这允许浏览器为不同的task source设置不同的优先级,比如为用户交互设置更高优先级来使用户感觉流畅。
示例
参考文献:
从Promise来看JavaScript中的Event Loop、Tasks和Microtasks
JavaScript Event Loop 机制详解与 Vue.js 中实践应用
JavaScript 运行机制详解:再谈Event Loop
The text was updated successfully, but these errors were encountered: