宏任务与微任务

文章介绍了JavaScript中的调用栈、堆和事件循环的概念,以及宏任务和微任务在异步操作中的作用。宏任务包括setTimeout等,微任务如Promise.then,微任务总在当前宏任务执行完毕后立即执行。理解这些概念有助于优化异步代码的执行效率。
摘要由CSDN通过智能技术生成

在JavaScript中,我们经常听到宏任务和微任务这两个概念,它们往往涉及到异步操作以及事件循环。在深入了解它们之前,我们需要先了解一下JavaScript中的调用栈、堆和事件循环。

调用栈、堆和事件循环

在JavaScript中,调用栈(call stack)是一个存储函数调用的栈结构,每当执行一个函数时,该函数会被压入调用栈中,当该函数执行完后,它就从调用栈中弹出。

而堆(heap)则是存储对象的地方,变量不存储在堆中,但它们会指向堆中的对象。堆中的数据可以被多个变量引用,因此可以说是共享的。

事件循环(event loop)是一种机制,它能够让JavaScript处理异步操作。当发生异步操作时,事件循环将其放入队列中,然后等待JavaScript引擎把调用栈清空后再处理队列中的操作。

宏任务与微任务

在JavaScript中,任务可以分为宏任务和微任务。

宏任务(macrotask)包括以下几种:

  • setTimeout
  • setInterval
  • setImmediate
  • I/O 操作
  • UI 渲染

而微任务(microtask)包括以下几种:

  • Promise.then()
  • Object.observe()
  • MutationObserver
  • process.nextTick()(Node.js独有)

执行一个宏任务的过程是这样的:当宏任务被放入队列中时,事件循环会等待调用栈清空后再去执行该宏任务。如果在执行宏任务的过程中发现了微任务,那么这些微任务会被全部放入微任务队列中等待处理。

而执行一个微任务的过程则比较特殊,它是在当前宏任务执行完毕但调用栈还没有清空时触发的。也就是说,只有当当前宏任务执行完毕才会去执行所有的微任务。

下面以一个例子来说明宏任务和微任务的执行顺序:

 
console.log('start');

setTimeout(function() { console.log('timeout'); }, 0); 
Promise.resolve().then(function() { console.log('promise'); });

console.log('end');

上面的代码输出的结果为:

start end promise timeout

setTimeout(function(){
    console.log(1);
});
new Promise(function(resolve){            
    console.log(2);
    resolve();
}).then(function(){            
    console.log(3);
}).then(function(){
    console.log(4)
});         
console.log(5);
// 2 5 3 4 1

解答:
1. 遇到setTimout,异步宏任务,放入宏任务队列中
2. 遇到new Promise,new Promise在实例化的过程中所执行的代码都是同步进行的,所以输出2
3. Promise.then,异步微任务,将其放入微任务队列中
4. 遇到同步任务console.log(5);输出5;主线程中同步任务执行完
5. 从微任务队列中取出任务到主线程中,输出3、 4,微任务队列为空
6. 从宏任务队列中取出任务到主线程中,输出1,宏任务队列为空

可以看到,先执行了start和end两个宏任务,然后又产生了一个微任务(Promise),接着执行下一个宏任务(setTimeout),最终输出结果为promise和timeout。

如何使用宏任务和微任务

当我们开发JavaScript应用时,通常需要使用异步操作来处理一些其他线程、网络请求或用户输入等事件。在这种情况下,由于JavaScript是单线程的,需要使用异步回调函数来处理这些事件。在这个过程中,我们可以使用宏任务和微任务来优化代码的执行。

在使用宏任务和微任务时,需要注意以下几点:

  • 当我们需要执行异步操作时,可以将该异步操作放入宏任务队列中等待执行。
  • 当我们需要在异步操作完成后执行一些操作时,可以将这些操作放入微任务队列中等待执行。
  • 尽可能地使用微任务来处理异步操作,因为微任务的执行时间比宏任务短,能够更快地响应用户操作。
  • 避免嵌套过多的异步操作,因为这样会导致调用栈很长,影响性能。

总之,在JavaScript中,宏任务和微任务是优化异步操作的重要工具,合理地使用它们能够提高代码的执行效率和用户体

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值