事件循环机制(同步事件,宏任务、微任务「大厂真题解析」)

目录

 引言

实操1

实操2

实操3


 引言

        Js 是单线程,多任务执行时会触发进程阻塞问题。所以,Js 有两种任务的执行模式:同步和异步。

同步任务:运行在主线程,先于异步任务执行

异步任务:分为宏任务和微任务,微任务先于宏任务执行

        微任务:process.nextTick、Promise.then/ catch/finally、async修饰的函数,默认返回 Promise 对象

        宏任务:setTimeout、setInterval、ajax请求、文件读写操作 

实操1

        async function async1() {
            console.log('async1 start');
            await async2();
            console.log('async1 end');
        }
        async function async2() {
            console.log('async2');
            // await console.log('async21');// 这一行改变'async1 end' 'promise2'输出顺序
        }
        console.log('script start');
        setTimeout(() => {
            console.log('setTimeout');
        }, 0);
        async1();
        new Promise(function(resolve) {
            console.log('promise1');
            resolve();
        }).then(function() {
            console.log('promise2');
        });
        console.log('script end');
结果:
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout

解释:
先async 声明俩个函数但未执行;随之执行同步语句 script start;
接着 setTimeout 进入宏任务队列,执行async1() 输出async1 start; 
到达await async2() 立即执行async2() 输出 async2;
而后面的语句console.log('async1 end') 进入微任务队列;
继续往后到达 new Promise 开始执行输出promise1;
遇见resolve() 需要通过 .then 得结果,其进入微任务队列,无输出;
(到此,微任务队列有:async1 end,promise2 ;宏任务队列有:setTimeout)
接着同步语句输出script end;
然后,依次输出微任务:async1 end,promise2 
然后,依次输出宏任务:setTimeout

async await与微任务 - dnoyeb - 博客园 (cnblogs.com)

实操2

console.log(1);
 
async function asyFunction () {
    console.log(2);
    await console.log(3);
    await console.log(4);
    console.log(5);
    return 6
}
 
new Promise((resolve, reject) => {
    console.log(10);
    resolve();
}).then(res => {
    console.log(11);
})
 
console.log(7);
 
 
setTimeout(() => {
    console.log(8)
}, 2000)
 
setTimeout(() => {
    console.log(9)
}, 1000)
 
asyFunction().then(res => { console.log(res) });
结果:1 10 7 2 3 11 4 5 6 9 8
解释:
首先,执行同步语句,输出1
接着async 声明一个函数但未执行;随之执行 new Promise 输出10,并将.then(11)放进微队列
然后,执行同步语句,输出7;接着俩个 setTimeout 进入宏队列
最后执行前面声明的异步函数,立即输出 2 ,3(类似第一题)
没有输出4是因为前一个await,将其 及后的 .log(5)均放入微队列
接着 return 6 由该异步函数的.then 接住放入微队列
到此,微队列里依次是 11 4 5 6,逐个输出
而宏队列的由延迟时间大小,依次输出 9 8

 实操3(nextTick)

1、

setImmediate(function () {
  console.log(1);
}, 0);
setTimeout(function () {
  console.log(2);
}, 0);
new Promise(function (resolve) {
  console.log(3);
  resolve();
  console.log(4);
}).then(function () {
  console.log(5);
});
console.log(6);
process.nextTick(function () {
  console.log(7);
});
console.log(8);

// 3 4 6 8 7 5 2 1

2、 

//加入两个nextTick的回调函数
process.nextTick(function () {
  console.log('nextTick延迟执行1');
});
process.nextTick(function () {
  console.log('nextTick延迟执行2');
});
// 加入两个setImmediate()的回调函数
setImmediate(function () {
  console.log('setImmediate延迟执行1');
  // 进入下次循环 
  process.nextTick(function () {
    console.log('强势插入');
  });
});
setImmediate(function () {
  console.log('setImmediate延迟执行2');
});

console.log('正常执行');
正常执行
nextTick延迟执行1
nextTick延迟执行2
setImmediate延迟执行1
强势插入
setImmediate延迟执行2

3、


console.log("start");
process.nextTick(() => {
  console.log("a");
  setImmediate(() => {
    console.log("d");
  });
  new Promise(res => res()).then(() => {
    console.log("e");
    process.nextTick(() => {
      console.log("f");
    });
    new Promise(resolve => {
      resolve()
    })
      .then(() => {
        console.log("g");
      });
    setTimeout(() => {
      console.log("h");
    });
  });
});

setImmediate(() => {
  console.log("b");
  process.nextTick(() => {
    console.log("c");
  });
  new Promise(res => res()).then(() => {
    console.log("i");
  });
});
console.log("end");

// start end a e g f h b c i d 

总结:

  • 同步代码执行顺序优先级高于异步代码执行顺序优先级;
  • new Promise(fn)中的fn是同步执行;
  • process.nextTick()>Promise.then()>setTimeout>setImmediate。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小白目

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

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

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

打赏作者

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

抵扣说明:

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

余额充值