关于js宏任务和微任务的理解


js的宏任务和微任务(作者:老司机)

一、前提(随便过一下)

  1. 同步与异步
  • 异步代码,如通过事件注册的回调,调用时,特点是调用后立即返回,到没有得到结果(后续通过回调函数获取)
  • 同步代码,逐行执行的代码,特点是调用后,要等待该调用执行完毕,否则不会往下执行(调用返回后,结果也拿到了),如全局代码、非回调函数
  1. 事件循环:js是单线程语言(单线程执行代码),通过该机制高效执行代码
  2. 调用栈:当调用函数时,就会开辟内存空间(压栈),调用完毕后就会释放内存
  3. 队列:当某个事件有结果后,该事件所注册的回调函数被推入队列中,等待读入主线程执行(主线程空闲后就会执行该步骤)

二、宏任务

  • 在调用栈中直接执行的代码,如:全局代码、定时器(setInterval)、延迟器(setTimeout)、promise、function(一般的函数)等,其中一个函数可认为是一个宏任务

三、微任务

  • 微任务是在执行某些宏任务时产生的,它们会在执行下一个宏任务之前执行,如:Promise.then等

四、示例代码

/**
 * - 事件循环第一轮:执行宏任务1【testPromise()、setTimeout()、console.log(123)】
 * 其中,testPromise().then()生成了一个微任务,两个setTimeout()注册了两个回调函数,执行完毕后,开始执行本轮事件循环产生的微任务then()
 * - 事件循环第二轮:(假如已经在某一刻将回调函数推入队列)读取一个延迟器注册的函数到主线程执行,该轮事件循环没有微任务
 * - 事件循环第三轮:读取一个延迟器注册的回调到主线程执行...
 */
function testPromise() {
    return new Promise(function (resolve) {
        resolve("----> Promise");
    });
}

testPromise().then(function (r) {
    console.log(r)
});

setTimeout(function () {
    console.log("-----> setTimeout 1");
});

setTimeout(function () {
    console.log("-----> setTimeout 2");
});

console.log(123);

  目录