JS事件循环与任务队列(宏任务与微任务先后顺序,最全!!!)

事件循环与任务队列是面试高频考点,本文便总结了任务队列各种情况。
下面我们先来说事件循环:
因为js是单线程运行,那么流程可以概括为:

  • 步骤一:主线程读取JS代码,此时为同步环境,形成相应的堆和执行栈;
  • 步骤二:当主线程遇到异步操作的时候,将异步操作交给相应的API进行处理;
  • 步骤三:异步操作处理完成,推入任务队列
  • 步骤四:主线程查询任务队列,执行微任务,按顺序执行。
  • 步骤五:主线程查询任务队列,执行微任务,按顺序执行。
  • 重复四、五步骤;

接下来就是本文的重点咯,任务队列中的宏任务与微任务的输出顺序。

  • 先执行 宏任务当中的同步任务 --> 微任务当中的同步任务 --> 微任务当中的异步任务 --> 宏任务中的异步任务
  • 宏任务 setTimeout setInterval setImmediate 也有先后顺序 先执行setTimeout 后执行 setImmediate I/O UI
  • 微任务 promise.then() process.nextTick 有先后顺序 promise.then() 后执行
new Promise(function (resolve) {
    console.log('1');
    resolve();
}).then(function () {
    console.log('2')
})
process.nextTick(function () {
    console.log('3');
})
setImmediate(() => {
    console.info('4')        //    1   5   3   2   6   7   10   9   11  4   8   
})
new Promise(function (resolve) {
    console.log('5');
    resolve();
}).then(function () {
    console.log('6')
})
setTimeout(function () {
    console.log('7');
    setImmediate(() => {
        console.info('8')
    })
    process.nextTick(function () {
        console.log('9');
    })
    new Promise(function (resolve) {
        console.log('10');
        resolve();
    }).then(function () {
        console.log('11')
    })
});

然后还有最关键的async函数的await与上述的关系呢?

如果 await 的是 promise对象,await 会暂停 async 函数内后面的代码,先执行 async 函数外的同步代码(注意,promise 内的同步代码会先执行),等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果返回后,再继续执行 async 函数内后面的代码

function sleep(second) {
    return new Promise((resolve, reject) => {
    	consol.log('aaaa)
        setTimeout(() => {
            resolve(' enough sleep~');
        }, second);
    })
}
async function awaitDemo() {
    let result = await sleep(2000);
    console.log(result);// 两秒之后会被打印出来
}
console.log("主线程1")
awaitDemo();
console.log("主线程2")
//主线程1
//aaaa
//主线程2
//enough sleep~

如果 await 的不是一个 promise ,而是一个表达式。await 会暂停 async 函数内后面的代码执行,先执行 async 函数外的同步代码(注意,此时会先执行完 await 后面的表达式后再执行 async 函数外的同步代码)

function sleep(second) {
 	return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(' enough sleep~');
        }, second);
    })
}
function normalFunc() {
    console.log('normalFunc');
}
async function awaitDemo() {
    await normalFunc();
    console.log('something, ~~');
    let result = await sleep(2000);
    console.log(result);// 两秒之后会被打印出来
}
console.log("主线程1")
awaitDemo();
console.log("主线程2")
//主线程1
//normalFunc
//主线程2
//something, ~~
//enough sleep~

应该出的难度就是这么多的情况吧,应该不会更难(可能我还是小白,见识浅)。如有出错,欢迎批评指正。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
JS的循环机制是指如何处理事件循环中的任务。在JS中,事件循环是一种机制,用于处理异步操作和事件处理。循环机制确保任务按照正确的顺序执行,以保证代码的正确性和性能。 在循环机制中,有两种类型的任务宏任务(macro-task)和微任务(micro-task)。宏任务包括整体代码块、setTimeout、setInterval等,而微任务包括Promise、MutationObserver、process.nextTick等。 当代码执行时,会首先执行当前代码块中的同步任务,然后执行微任务队列中的所有微任务。接下来,会从宏任务队列中选择一个任务执行,直到宏任务队列为空。然后,再次执行所有微任务,以此类推。 事件队列是用来存储待执行的任务的数据结构。每个宏任务微任务都会被添加到事件队列中。当事件循环开始时,会从事件队列中依次取出任务并执行。 需要注意的是,微任务的优先级高于宏任务。也就是说,在执行完当前宏任务后,会立即执行所有微任务,然后再执行下一个宏任务。这样可以确保微任务能够尽早地被执行,避免出现不必要的延迟。 总结一下: - 循环机制确保异步任务按照正确的顺序执行。 - 宏任务包括整体代码块、setTimeout、setInterval等。 - 微任务包括Promise、MutationObserver、process.nextTick等。 - 事件队列用来存储待执行的任务。 - 微任务优先级高于宏任务
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夕&月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值