美文网首页
我眼中的event loop

我眼中的event loop

作者: CodorMonkey | 来源:发表于2018-05-23 15:25 被阅读0次
科普一波
  1. js执行是单线程的,执行顺序是 macro-task -> micro-task -> macro-task -> ... 交替执行
  2. macro-task,以下简称macro,包含:js整体代码、setTimeout、setInterval、setImmediate、IO、UI rendering
  3. micro-task,以下简称micro,包含:process.nextTick、Promises(这里指浏览器实现的Promise)、Object.observe(已废弃)、MutationObserver
上代码(执行环境为Node 8.9.4)
setImmediate(function () {
  console.log(14);
});

setTimeout(function () {
  console.log(13)
});

process.nextTick(function () {
  console.log(4);
});

new Promise(function (resolve) {
  console.log(1);

  for (let i = 0; i < 10000; i++) {
    i === 9999 && resolve()
  }

  console.log(2);

  process.nextTick(function () {
    console.log(5);
  });
}).then(function () {
  console.log(6);

  process.nextTick(function () {
    console.log(10);
  });

  new Promise(function (resolve) {
    console.log(7);
    resolve();
    console.log(8);
    process.nextTick(function () {
      console.log(11);
    });
  }).then(function () {
    console.log(9);
    process.nextTick(function () {
      console.log(12);
    });
  })
});

console.log(3);

执行结果为 1 2 3 ... 14

开始分析
  • 第一轮
    执行macro,也就是js代码,输出1 2 3;
    此时micro中注册了[4 5 <包含6~12的Promise.then代码块>],macro中注册了[13 14];
    macro已经清空,之后执行micro;

  • 第二轮
    执行micro,输出4 5,可以看出process.nextTick优先级高于Promise.then;
    接着执行micro,执行<包含6~12的Promise.then代码块>,首先输出6 7 8,此时micro再次注册[10 11 <包含9 12的Promise.then代码块>];
    接着执行micro,按照上面得出的结论,讲道理输出顺序为 10 11 9 12,实际输出为 9 10 11 12,为什么会这样呢?

  • 下面开始分析,纯属猜测!!!
    本人能想到的就是,micro不止一个,process.nextTick拥有单独的micro-task队列;
    回头看<包含6~12的Promise.then代码块>,首先输出 6 7 8,没毛病;
    此时nextTick独有的micro注册了[10 11],当前micro还注册了[<包含9 12的Promise.then代码块>];
    由于当前micro还没执行完,接着执行<包含9 12的Promise.then代码块>,此时输出 9,并且向nextTick独有的micro注册了12,
    此时nextTick独有的micro包含 [10 11 12],这时,当前micro已经清空,接着执行nextTick的micro,输出 10 11 12;
    这样就与实际情况相符了~,不过,以上纯属个人猜测!!!

  • 最后一轮
    执行macro,输出 13 14,可以看出setTimeout优先级高于setImmediate;

相关文章

网友评论

      本文标题:我眼中的event loop

      本文链接:https://www.haomeiwen.com/subject/mjmrjftx.html