Web高级 Eventloop和事件执行顺序

1. EventLoop

1.1 调用栈

当一个方法执行时内部调用另外的方法,则会形成调用栈,如图:

Web高级 Eventloop和事件执行顺序

1.2 任务队列

JavaScript有一个主线程执行当前任务,主线程的代码同步执行,并把遇到的事件和回调注册到事件表中。

当事件表中的事件被触发时,将会把对应的处理函数推送到任务队列当中。

Web高级 Eventloop和事件执行顺序

每一次EventLoop会从任务队列中获取最前面的事件处理函数进行执行。

  • macrotasks queue(图中task queue)

    包括: 整体代码script,setTimeout,setInterval,setImmediate,I/O,UI渲染
  • microtasks queue

    包括: Promise process.nextTick Object.observe MutationObserver

注意:每一次Eventloop拥有独立的微任务队列,在每次同步调用堆栈结束后,会检查微任务队列中是否有需要处理的事件,如果有就进行调用.

1.3 事件循环

当一轮事件循环结束后(Fun1),进行下一轮循环(Fun2).

事件执行顺序

根据macrotasks队列和microtasks队列的执行时机不同,因此需要注意异步代码的执行顺序

其原则是:

  1. macrotasks将进入宏任务队列,将在下一次eventloop时进行调用(先进先出)

    常见的包括XHR,JSONP,setTimeout,setInterval等
  2. microtasks将进入微任务队列,在当前eventloop结束前进行调用

    microtasks常见的有Promise.then,process.nextTick(nodejs)等
console.log(1)
setTimeout(()=>{console.log(2)},0);
Promise.resolve(console.log(3)).then(()=>{console.log(4)});
var ps = new Promise((resolve,reject)=>{console.log(5);resolve(1)});
ps.then(()=>{console.log(6)});
var fs = new Promise((filename)=>{return file.read(filename)});
fs.then((rs)=>{console.log(7)});
//1,3,5,4,6,7,2

refs:

https://github.com/ccforward/cc/issues/48

https://html.spec.whatwg.org/multipage/webappapis.html#task-queue

上一篇:VC++ 学习笔记2 列表框添加字符串


下一篇:element-ui table表格展开行每次只能展开一行