JS事件循环机制:同步任务,宏任务,微任务

同步任务,宏任务,微任务

同步任务、宏任务和微任务属于 JavaScript 中的事件循环机制的问题。在 JavaScript 运行环境中,存在一个主线程和任务队列,所有代码都会被排入任务队列中。当主线程空闲时,它会从任务队列中取出一个任务并执行。而 JavaScript 中的任务可以分为同步任务、宏任务和微任务三种类型,它们在任务队列中的排列顺序不同。

同步任务是直接在主线程上执行的任务,按照顺序依次执行。

而宏任务和微任务则是异步执行的任务,会先被放入对应的任务队列中,等待主线程上的任务执行完毕后再去取出并执行宏任务和微任务。不同的是宏任务和微任务的执行顺序不同:

  • 宏任务包括 setTimeout、setInterval、I/O、UI Rendering 等任务,会被放入宏任务队列中,等待主线程执行的同步任务执行完毕后,再去取出并执行宏任务队列中的任务。

  • 微任务包括 Promise、process.nextTick、Object.observe、MutationObserver 等任务,会被放入微任务队列中,等待主线程执行的同步任务以及宏任务队列中的任务执行完毕后,再去取出并执行微任务队列中的任务。

因此,在 JavaScript 运行环境中,我们要了解事件循环机制以及同步任务、宏任务和微任务的执行顺序,才能正确地理解代码的执行过程和结果。

JavaScript 中任务的执行顺序如下:

  1. 执行同步任务,即按照顺序执行的任务。

  2. 执行当前宏任务队列中的一个任务,例如 setTimeout、setInterval、setImmediate 等。

  3. 执行所有可立即执行的微任务队列中的任务,例如 Promise、process.nextTick 等。

  4. 回到宏任务队列中,执行下一个宏任务,重复步骤 2 和 3。

JavaScript 中异步任务的执行顺序遵循任务队列机制。在一个事件循环周期中,可能存在多个宏任务(例如 setTimeout、setInterval 等),以及一个微任务队列(例如 Promise、process.nextTick 等)。每当一个宏任务执行完毕后,会依次从微任务队列中取出一个任务执行,直到所有的微任务都执行完毕;然后才会开始下一个宏任务的执行。

下面是一个代码示例,演示了上述执行顺序的过程:

console.log(1);

setTimeout(() => {
    
    
  console.log(2);
  Promise.resolve(3).then(data => console.log(data));
})

Promise.resolve(4).then(data => console.log(data));

console.log(5);

这段代码的执行结果是:1 5 4 2 3。

解释如下:

  1. 执行同步任务,输出 1。
  2. 执行 setTimeout(() => {console.log(2);...}),将回调函数放入宏任务队列中。
  3. 执行 Promise.resolve(4).then(data => console.log(data)),将回调函数放入微任务队列中。
  4. 执行 console.log(5),输出 5。
  5. 执行微任务队列中的回调函数,输出 4。
  6. 取出宏任务队列中的回调函数并执行,输出 2。
  7. 执行 Promise.resolve(3).then(data => console.log(data)),将回调函数放入微任务队列中。
  8. 执行微任务队列中的回调函数,输出 3。

需要注意的是,setTimeout 会将所在的函数加入到宏任务队列中,而 Promise.resolve.then 会将回调函数加入到微任务队列中。在遇到微任务队列时,必须要执行完所有的微任务,才会执行下一个宏任务。

猜你喜欢

转载自blog.csdn.net/qq_51532249/article/details/130923057