Johnqing / johnqing.github.com

http://liluo.me
1 stars 2 forks source link

event loop #5

Open Johnqing opened 6 years ago

Johnqing commented 6 years ago

市面上有很多类似的文章吧,这篇是我自己的理解。

单线程?

js从发明到现在贡献最多的还是浏览器层面,所以从整体架构上来看,为了解决多线程造成的麻烦,js相关的引擎一直是按照单线程的方式在工作。

但是在引擎(v8)层面,如果要实现异步回调,还是要借助多线程来做。大概的操作如下:

  1. 注册一个回调到事件队列中,会有一个标志来保证唯一性。
  2. 执行队列从事件队列中取出相应的操作,并且执行。
  3. 如果是timer类型等,延迟执行。
  4. 执行完成返回到回调队列,并且按照标志,返回。

以上是引擎底层调用的大概步骤。但是会有一个疑问,如何保证timer、promise的执行时机呢?

异步任务

执行异步任务时,拆分了2组任务来执行。宏任务和微任务。

宏任务

包含:

引擎会优先执行宏任务,每次一组(同步脚本默认为同一组)。

微任务

包含:

引擎会在执行为一组宏任务后执行当前所有的微任务。

注意

虽然timer类型的会优先执行,但是因为时间未到(最少40毫秒),所以会被放到事件队列中等待执行,所以会晚于微任务

setTimeout(function(){console.log(1)}, 0);
function wait(duration){
    console.log(2);
    return new Promise(function(resolve, reject) {
        console.log(3);
        resolve();
        console.log(4);
    })
}
wait().then(function(){console.log(5)});
setTimeout(function(){console.log(6)}, 0);
// 234516