前端中的宏任务与微任务详解

发布时间:2024年01月02日

在前端开发中,了解和处理异步操作对于提升用户体验和代码性能至关重要。浏览器按照一定的规则调度和管理这些异步操作,其中宏任务和微任务是两种主要的调度方式。这篇文章将详细解释这两种任务类型,并给出相关的代码示例。

宏任务

宏任务是指在当前执行栈执行完毕后立即执行的任务。这些任务通常是由外部环境触发的,例如:

  • setTimeout
  • setInterval
  • setImmediate(仅在Node.js中)
  • I/O
  • UI渲染
  • 事件监听器的回调

这些任务会被添加到宏任务队列中等待执行。

微任务

微任务通常是由程序本身产生的,这些任务会在当前执行栈中的任务执行完毕后、下一个宏任务开始之前执行。微任务包括:

  • Promise.then
  • Promise.catch
  • Promise.finally
  • process.nextTick(Node.js特有)
  • MutationObserver

这些任务会被添加到微任务队列中,等待当前执行栈清空后立即执行。

代码示例

下面是一个使用 Promise 的微任务示例:

let promise = new Promise((resolve, reject) => {
  // 这是一个宏任务
  setTimeout(() => {
    // 这是一个微任务
    console.log('MacroTask done.');
    resolve('MacroTask resolved.');
  }, 0);
});

promise.then((value) => {
  console.log('Promise resolved:', value);
});

这段代码首先设置一个 setTimeout,它在宏任务队列中排队。当 setTimeout 的宏任务被执行完毕后,Promise 会接收到一个微任务来执行。这时,console.log 会被标记为微任务,并且在当前执行栈清空后立即执行。接着,Promise 返回一个新的 Promise 对象,并且根据宏任务的完成情况调用 resolve 或 reject 方法。在代码的最后,我们等待并处理这个 Promise 的结果。

另一个代码示例:

console.log('Script start'); // 宏任务

setTimeout(function() {
    console.log('setTimeout'); // 宏任务
}, 0);

Promise.resolve().then(function() {
    console.log('promise1'); // 微任务
}).then(function() {
    console.log('promise2'); // 微任务
});

console.log('Script end'); // 宏任务

在这个例子中,执行顺序为:

  1. Script start
  2. Script end
  3. promise1
  4. promise2
  5. setTimeout

理解宏任务和微任务可以帮助我们在前端开发中进行各种优化。例如我们可以通过使用 Promise 和 setTimeout 等微任务来实现更高效的定时操作,通过使用 MutationObserver 和其他微任务来监控 DOM 变化,提高页面更新效率。了解和正确使用微任务队列也可以避免一些常见的编程错误,如忘记在回调函数中返回 Promise 等。

执行顺序

  1. 执行同步代码,这些代码属于宏任务。
  2. 执行栈为空后,查询是否有微任务需要执行。
  3. 执行所有微任务。
  4. 必要的话进行UI渲染。
  5. 开始下一轮Event Loop,执行宏任务中的一个任务。

总结

通过这篇文章,我们了解了前端开发中的宏任务和微任务的概念和区别,并给出了相关的代码示例。了解这两种任务的特性和使用场景,可以帮助我们更好地编写异步代码,提高代码的执行效率,并避免常见的编程错误。在复杂的应用中,这个知识点尤其关键,因为它直接影响到事件处理和UI的更新。随着前端技术的发展,我们会看到更多的应用场景和优化方法,这些都需要我们深入理解和掌握前端中的宏任务和微任务。


看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~

专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)

文章来源:https://blog.csdn.net/qq_37247349/article/details/135339134
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。