事件循环的两道面试题

时间:2021-08-17
本文章向大家介绍事件循环的两道面试题,主要包括事件循环的两道面试题使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

事件循环(Event Loop)

浅谈Event Loop (juejin.cn)

进程和线程

JS为什么是单线程?

假设js同时有两个线程,一个线程想要在某个dom节点上增加内容,另一个线程想要删除这个节点,这时要以哪个为准呢?

JavaScript是单线程的,浏览器是多进程的,当打开一个tab页面就会开启一个新的进程,每个进程中又包含很多的线程,其中包括执行JavaScript代码的线程。
但是js的代码执行是在一个单独的线程中执行的,在同一个时刻只能做一件事情。

同步与异步

更详细的可以看链接:https://juejin.cn/post/6844904072068218887

  1. js在执行代码时,代码首先进入执行栈,代码中可能包含一些同步任务和异步任务。
  2. 同步任务立即执行,执行完出栈,over。
  3. 异步任务也就是常见的ajax请求、setTimeout等,代码调用到这些api的时候,WebAPIs来处理这些问题,执行栈继续执行。
  4. 异步任务有了运行结果时,(当ajax请求结果返回时),WebAPIs把对应的回调函数放到任务队列。
  5. 执行栈为空时来读取任务队列中的第一个函数,压入执行栈。

步骤5不断重复,执行栈为空时,系统就去任务队列中拿第一个函数压入栈继续执行。这个过程不断重复,这就是事件循环(Event Loop)。

微任务与宏任务

  • 常见的宏任务:script(整体代码)setTimeoutsetIntervalI/OsetImmedidate
  • 常见的微任务:process.nextTickMutationObserverPromise.then catch finally

process.nextTicksetImmidate是只支持Node环境的。

还有,process.nextTick是有一个插队操作的,就是说他进入微任务队列时,会插到除了process.nextTick 其他的微任务前面。

面试题

setTimeout(function () {
  console.log("set1");
  new Promise(function (resolve) {
    resolve();
  }).then(function () {
    new Promise(function (resolve) {
      resolve();
    }).then(function () {
      console.log("then4");
    });
    console.log("then2");
  });
});

new Promise(function (resolve) {
  console.log("pr1");
  resolve();
}).then(function () {
  console.log("then1");
});

setTimeout(function () {
  console.log("set2");
});

console.log(2);

queueMicrotask(() => {
  console.log("queueMicrotask1")
});

new Promise(function (resolve) {
  resolve();
}).then(function () {
  console.log("then3");
});

// pr1
// 2
// then1
// queuemicrotask1
// then3
// set1
// then2
// then4
// set2

async function async1 () {
  console.log('async1 start') // 2
  await async2();
  console.log('async1 end') // 放到微任务队列1  // 6
}
 
async function async2 () {
  console.log('async2') // 3
}

console.log('script start') // 1

setTimeout(function () {
  console.log('setTimeout') // 宏任务队列1 // 8 
}, 0)
 
async1();
 
new Promise (function (resolve) {
  console.log('promise1') // 4
  resolve();
}).then (function () {
  console.log('promise2') // 微任务队列2 // 7
})

console.log('script end') //5 


// script start
// async1 start
// async2
// promise1
// script end
// aysnc1 end
// promise2
// setToueout

原文地址:https://www.cnblogs.com/lijinbudaily/p/15152846.html