js中事件循环执行的顺序

在前端面试过程中,经常会出现这样的问题,event loop事件循环机制是什么样的呢?查询相关资料,了解到的大概的以下的一个流程。
第一,先执行全局的javascript的代码。
第二,执行全局范围内微任务中的所有任务。
第三,从宏任务队列中取出一个宏任务来执行,顺序为:一个宏任务—所有微任务—一个宏任务—所有微任务…
但是这个太书面化了,经过不断尝试之后,将具体执行顺序总结如下,根据不同的情况分别进行列举:

一、全局范围内的js代码、new Promise、Promise.then、Promise.all().then()、process.nextTick的执行顺序

在这里面由于new Promise会立即执行,这里面的代码会按照顺序依次执行。相应的顺序为:有顺序的js代码 --> new Promise --> 有顺序的js代码(全局js和new Promise执行完毕之后) --> 所有的process.nextTick --> Promise().then() --> Promise.all().then()

console.log(1);// 顺序-1

Promise.all([new Promise(resolve => {
	console.log(2);// 顺序-2
	resolve(100);
})]).then(values => {
  console.log(values);// 顺序- 10
});

process.nextTick(() => {
  console.log(6);// 顺序- 6
});

new Promise((resolve) => {
  console.log(3);// 顺序-3
  resolve('3-1');
}).then(values => {
  console.log(values);// 顺序- 8
});

console.log(4);// 顺序- 4

new Promise((resolve) => {
  console.log(5);// 顺序- 5
  resolve('5-1');
}).then(values => {
  console.log(values);// 顺序- 9
})
process.nextTick(() => {
  console.log(7);// 顺序- 7
})

二、涉及到setTimeout,以及定时器里面有new Promise、Promise.then、Promise.all的情况

这种情况的执行顺序是在第一种情况都执行完毕之后才会执行。执行顺序为:
多个定时器时间相同:按照顺序执行setTimeout。定时器里的执行顺序为,顺序执行js代码 --> new Promise --> 有顺序的js代码(js和new Promise执行完毕之后) --> 所有的process.nextTick --> Promise().then() --> Promise.all().then()。这实际就是重复第一种情况中的执行顺序。

setTimeout(() => {
  console.log("setTimeout1");// 顺序-- 1
  new Promise((resolve) => {
    console.log('setTimeout1 --- Promise');// 顺序-- 2
    resolve('Promise-1');
  }).then((values) => {
    console.log(values);// 顺序-- 5
  });
}, 0)
setTimeout(() => {
  console.log("setTimeout2");// 顺序-- 3
  new Promise((resolve) => {
    console.log('setTimeout2 --- Promise');// 顺序-- 4
    resolve('Promise-2');
  }).then((values) => {
    console.log(values);// 顺序-- 6
  });
}, 0)

多个定时器时间不同:按照setTimeout的时间长短排序进行,setTimeout时间短的先执行,时间长的后执行。其中每个定时器里的执行顺序同上。

setTimeout(() => {
  console.log("setTimeout1");// 顺序-- 4
  new Promise((resolve) => {
    console.log('setTimeout1 --- Promise');// 顺序-- 5
    resolve('Promise-1');
  }).then((values) => {
    console.log(values);// 顺序-- 6
  });
}, 100)
setTimeout(() => {
  console.log("setTimeout2");// 顺序-- 1
  new Promise((resolve) => {
    console.log('setTimeout2 --- Promise');// 顺序-- 2
    resolve('Promise-2');
  }).then((values) => {
    console.log(values);// 顺序-- 3
  });
}, 0)

多个定时器中嵌套多层setTimeout,根据定时器时间长短进行区分,同一层级的setTimeout会根据时间先后按顺序执行。以下是针对时间相同的情况举例。

setTimeout(() => {
  console.log("setTimeout1");// 顺序-- 1
  new Promise((resolve) => {
    console.log('setTimeout1 --- Promise');// 顺序-- 2
    setTimeout(() => {
      console.log('setTimeout1 --- Promise---setTimeout');// 顺序-- 7
    }, 0)
    resolve('Promise-1');
  }).then((values) => {
    console.log(values);// 顺序-- 5
  });
}, 0)
setTimeout(() => {
  console.log("setTimeout2");// 顺序-- 3
  new Promise((resolve) => {
    console.log('setTimeout2 --- Promise');// 顺序-- 4
    setTimeout(() => {
      console.log('setTimeout2 --- Promise---setTimeout');// 顺序-- 8
    }, 0)
    resolve('Promise-2');
  }).then((values) => {
    console.log(values);// 顺序-- 6
  });
}, 0)

你可能感兴趣的:(js中事件循环执行的顺序)