Skip to content

Day1:请写出下面代码执行的的结果 #37

@Genzhen

Description

@Genzhen
Collaborator
console.log(1);
setTimeout(() => {
  console.log(2);
  process.nextTick(() => {
    console.log(3);
  });
  new Promise((resolve) => {
    console.log(4);
    resolve();
  }).then(() => {
    console.log(5);
  });
});
new Promise((resolve) => {
  console.log(7);
  resolve();
}).then(() => {
  console.log(8);
});
process.nextTick(() => {
  console.log(6);
});
setTimeout(() => {
  console.log(9);
  process.nextTick(() => {
    console.log(10);
  });
  new Promise((resolve) => {
    console.log(11);
    resolve();
  }).then(() => {
    console.log(12);
  });
});

每日一题会在下午四点在交流群集中讨论,五点小程序中更新答案
欢迎大家在下方发表自己的优质见解
二维码加载失败可点击 小程序二维码

扫描下方二维码,收藏关注,及时获取答案以及详细解析,同时可解锁800+道前端面试题。

Activity

Genzhen

Genzhen commented on Jun 22, 2020

@Genzhen
CollaboratorAuthor

答案
node <11:1 7 6 8 2 4 9 11 3 10 5 12
node>=11:1 7 6 8 2 4 3 5 9 11 10 12

解析

  • 宏任务和微任务
    • 宏任务:macrotask,包括setTimeout、setInerVal、setImmediate(node独有)、requestAnimationFrame(浏览器独有)、I/O、UI rendering(浏览器独有)
    • 微任务:microtask,包括process.nextTick(Node独有)、Promise.then()、Object.observe、MutationObserver
  • Promise构造函数中的代码是同步执行的,new Promise()构造函数中的代码是同步代码,并不是微任务
  • Node.js中的EventLoop执行宏队列的回调任务有6个阶段
    • 1.timers阶段:这个阶段执行setTimeout和setInterval预定的callback
    • 2.I/O callback阶段:执行除了close事件的callbacks、被timers设定的callbacks、setImmediate()设定的callbacks这些之外的callbacks
    • 3.idle, prepare阶段:仅node内部使用
    • 4.poll阶段:获取新的I/O事件,适当的条件下node将阻塞在这里
    • 5.check阶段:执行setImmediate()设定的callbacks
    • 6.close callbacks阶段:执行socket.on('close', ....)这些callbacks
  • NodeJs中宏队列主要有4个
    • 1.Timers Queue
    • 2.IO Callbacks Queue
    • 3.Check Queue
    • 4.Close Callbacks Queue
    • 这4个都属于宏队列,但是在浏览器中,可以认为只有一个宏队列,所有的macrotask都会被加到这一个宏队列中,但是在NodeJS中,不同的macrotask会被放置在不同的宏队列中。
  • NodeJS中微队列主要有2个
    • 1.Next Tick Queue:是放置process.nextTick(callback)的回调任务的
    • 2.Other Micro Queue:放置其他microtask,比如Promise等
    • 在浏览器中,也可以认为只有一个微队列,所有的microtask都会被加到这一个微队列中,但是在NodeJS中,不同的microtask会被放置在不同的微队列中。
  • Node.js中的EventLoop过程
    • 1.执行全局Script的同步代码
    • 2.执行microtask微任务,先执行所有Next Tick Queue中的所有任务,再执行Other Microtask Queue中的所有任务
    • 3.开始执行macrotask宏任务,共6个阶段,从第1个阶段开始执行相应每一个阶段macrotask中的所有任务,注意,这里是所有每个阶段宏任务队列的所有任务,在浏览器的Event Loop中是只取宏队列的第一个任务出来执行,每一个阶段的macrotask任务执行完毕后,开始执行微任务,也就是步骤2
    • 4.Timers Queue -> 步骤2 -> I/O Queue -> 步骤2 -> Check Queue -> 步骤2 -> Close Callback Queue -> 步骤2 -> Timers Queue ......
    • 5.这就是Node的Event Loop
  • Node 11.x新变化
    • 现在node11在timer阶段的setTimeout,setInterval...和在check阶段的immediate都在node11里面都修改为一旦执行一个阶段里的一个任务就立刻执行微任务队列。为了和浏览器更加趋同.
can-dy-jack

can-dy-jack commented on May 2, 2022

@can-dy-jack

宏任务里的setInterval打错了,您打成了setInerVal(不是故意挑刺,就是追求完美🫡

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @Genzhen@can-dy-jack

        Issue actions

          Day1:请写出下面代码执行的的结果 · Issue #37 · lgwebdream/FE-Interview