Skip to content
New issue

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

Event Loop #67

Open
rogerxu opened this issue Feb 12, 2017 · 3 comments
Open

Event Loop #67

rogerxu opened this issue Feb 12, 2017 · 3 comments
Assignees

Comments

@rogerxu
Copy link
Owner Author

rogerxu commented Feb 12, 2017

Event loop: microtasks and macrotasks (javascript.info)

JavaScript 运行机制详解:再谈Event Loop - 阮一峰的网络日志

How JavaScript works: an overview of the engine, the runtime, and the call stack

How JavaScript works: inside the V8 engine + 5 tips on how to write optimized code

How JavaScript works: Event loop and the rise of Async programming + 5 ways to better coding with async/await | by Alexander Zlatkov | SessionStack Blog

你真的了解Event Loop(事件环)吗? - 掘金

JavaScript:彻底理解同步、异步和事件循环(Event Loop) - 追根溯源 - SegmentFault 思否

image

https://user-gold-cdn.xitu.io/2018/5/24/1639256db41f320b?imageView2/0/w/1280/h/960/format/webp/ignore-error/1
image

Micro Task

  • then()

Macro Task

  • setTimeout()
  • setInterval()
  1. 函数入栈,当Stack中执行到异步任务的时候,就将他丢给WebAPIs,接着执行同步任务,直到Stack为空;
  2. 此期间WebAPIs完成这个事件,把回调函数放入队列中等待执行(微任务放到微任务队列,宏任务放到宏任务队列)
  3. 执行栈为空时,Event Loop把微任务队列执行清空;
  4. 微任务队列清空后,进入宏任务队列,取队列的第一项任务放入Stack(栈)中执行,回到第1步。

@rogerxu
Copy link
Owner Author

rogerxu commented Apr 26, 2017

Node.js

Node 定时器详解 - 阮一峰的网络日志 (ruanyifeng.com)

The Node.js Event Loop, Timers, and process.nextTick() | Node.js (nodejs.org)

image

  1. 写的JavaScript脚本会交给V8引擎解析
  2. 解析后的代码,调用Node API,Node会交给Libuv库处理
  3. Libuv库将不同的任务分配给不同的线程,形成一个Event Loop(事件循环),以异步的方式将任务的执行结果返回给V8引擎
  4. V8引擎再将结果返回给用户

process.nextTick()

process.nextTick方法可以在当前"执行栈"的尾部----下一次Event Loop(主线程读取"任务队列")之前----触发回调函数。也就是说,它指定的任务总是发生在所有异步任务之前。

process.nextTick(function A() {
  console.log(1);
  process.nextTick(function B(){console.log(2);});
});

setTimeout(function timeout() {
  console.log('TIMEOUT FIRED');
}, 0)
// 1
// 2
// TIMEOUT FIRED

setImmediate()

setImmediate方法则是在当前"任务队列"的尾部添加事件,也就是说,它指定的任务总是在下一次Event Loop时执行,这与setTimeout(fn, 0)很像。

setImmediate(function A() {
  console.log(1);
  setImmediate(function B(){console.log(2);});
});

setTimeout(function timeout() {
  console.log('TIMEOUT FIRED');
}, 0);

运行结果可能是1--TIMEOUT FIRED--2,也可能是TIMEOUT FIRED--1--2。

@rogerxu rogerxu self-assigned this Sep 25, 2017
@rogerxu
Copy link
Owner Author

rogerxu commented May 25, 2018

宏任务和微任务

  1. macro-task: setTimeout, setInterval, setImmediate, I/O
  2. micro-task: process.nextTick, Promise (有些实现的promise将then方法放到了宏任务中), Object.observe(已废弃), MutationObserver

微任务通常来说就是需要在当前 task 执行结束后立即执行的任务。

console.log('script start');

setTimeout(function() {
  console.log('setTimeout');
}, 0);

new Promise((resolve, reject) => {
  console.log('in promise');
  resolve(1);
}).then(function() {
  console.log('promise1');
}).then(function() {
  console.log('promise2');
});

console.log('script end');
script start
in promise
script end
promise1
promise2
setTimeout

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant