事件循环案例讲解

您所在的位置:网站首页 经典案例讲解 事件循环案例讲解

事件循环案例讲解

2023-01-14 12:23| 来源: 网络整理| 查看: 265

事件循环机制:

执行顺序: 主任务 => 微任务 => 宏任务 宏任务:定时器(setTimeout setInterval、requestAnimationFrame)、事件绑定、ajax回调函数、node的fs模块 微任务: promise.then、 async await 、process.nextTick、queueMicrotask

案例1

console.log('start'); setTimeout(() => { console.log(333); }); // 安排明天干的活 Promise.resolve('x').then(() => { console.log(3); }).then(() => { console.log(4); }).then(() => { console.log(5); // 小任务无限的加 今天干完否则下不了班 //nodejs 有小任务限制,跳过直接到宏任务 }) console.log('end');

输出结果:

start => end => 3 => 4 => 5 =>333

解释:

一个微任务情况,依次执行完微任务

案例2

console.log('start'); setTimeout(() => { console.log(333); }); // 安排明天干的活 queueMicrotask(() => { console.log(1); queueMicrotask(() => { console.log(2); }); }) Promise.resolve('x').then(() => { console.log(3); }).then(() => { console.log(4); }).then(() => { console.log(5); // 小任务无限的加 今天干完否则下不了班 //nodejs 有小任务限制,跳过直接到宏任务 }) console.log('end');

输出结果:

start => end =>1 => 3 => 2 => 4 => 5 => 333

解释

当有多个微任务执行的时候 ,是交替执行

案例3

console.log(1); setTimeout(() => { console.log('大'); }) queueMicrotask(() => { console.log('小'); setTimeout(() => { console.log('大二'); }) }) console.log(2);

输出结果:

1 => 2 => 小 => 大 => 大二

console.log(1); queueMicrotask(() => { console.log('小一'); setTimeout(() => { console.log('大二'); }) }) setTimeout(() => { console.log('大三'); }) console.log(2);

输出结果:

1 => 2 => 小一 => 大三 => 大二

解释

当微任务内部嵌套宏任务, 执行完微任务之后 ,再看宏任务,且微任务中的宏任务会比同层级别的宏任务晚执行一天(小任务的大任务排队比同层级的更靠后执行),而不是打平结构看宏任务的先后顺序

案例4

console.log(1); setTimeout(() => { // f2 console.log('大'); queueMicrotask(() => { // f3 console.log('小一'); setTimeout(() => { //f5 console.log('大二'); }) }) }) queueMicrotask(() => { // f1 console.log('小二'); setTimeout(() => { // f4 console.log('大三'); }) }) console.log(2);

输出结果:

1 => 2 => 小二 => 大 => 小一 => 大三 => 大二

解释

当微任务内部嵌套宏任务,当宏任务内部嵌套微任务时依次,可打平结构依次对比: 微f1、同层级宏f2、宏内微f3、同宏内层级相同的宏f4,最内层宏f5,

案例5

console.log(111); setTimeout(() => { console.log('大'); }) Promise.resolve('x').then(() => { console.log('小'); Promise.resolve('x').then(() => { console.log('小2') //队友在前边 ,直接跟队友插队 }) }).then(() => { console.log('小3'); }) console.log(222);

输出结果:

111 => 222 => 小 => 小2 => 小3 => 大

解释

先一下执行完微任务 最后在看宏任务,且node v11之后的微任务是可以插队执行 node v11之前的执行顺序是小 => 小3 => 小2 (理解即微任务内部的微任务 要看下一层级的对比,和宏任务一样)

案例6

console.log('start'); new Promise(resolve => { console.log('p1'); }).then(() => { console.log(444); }).then(() => { console.log(555); }) Promise.resolve().then(() => { console.log(111); }).then(() => { console.log(222); }).then(() => { console.log(333); }) console.log('end');

输出结果:

start => p1 => end => 111 => 222 => 333

解释

start => p1 => end => 444 => 111 => 555 => 222 => 333 只有then里边的是微任务,new Promise的 resolve回调函数是主任务 这里444, 555没有执行是因为并没有执行promise.resolve

案例7

console.log('start'); new Promise(resolve => { console.log('p1'); resolve(4444); }).then(() => { console.log('resolved'); // 推迟两个 }) Promise.resolve().then(() => { console.log(111); }).then(() => { console.log(222); }).then(() => { console.log(333); }) console.log('end');

输出结果:

start => p1 => end => resolved => 111 => 222 => 333

解释

new Promise执行了回调函数 resolve() 则可以正常执行后续微任务

案例8

console.log('start'); new Promise(resolve => { console.log('p1'); let resolvedPromise = Promise.resolve(); resolve(resolvedPromise); }).then(() => { console.log('resolved'); // 推迟两个 }) Promise.resolve().then(() => { console.log(111); }).then(() => { console.log(222); }).then(() => { console.log(333); }) console.log('end');

输出结果:

start => p1 => end => 111 => 222 => resolved => 333

解释

start => p1 => end => 111 => 222 => resolved => 333 在Promise回调函数resolve()中执行Promise.resolve(); 会在本应该执行的基础上交替执行微任务的基础上,推迟两个微任务再执行该微任务

案例9

async function as1() { console.log('as1 start'); // 主任务2 await as2(); console.log('as1.end'); // await后 微任务1 前有await 放入异步等待队列中 } function as2() { console.log('as2'); } console.log('script start'); // 主任务1 setTimeout(() => { console.log('setTimeout') // 宏任务 }, 0); as1(); new Promise(function (resolved) { console.log('prom1'); // 主任务3 resolved(); }).then(function() { console.log('prom2'); // 微任务2 }) console.log('script end'); // 主任务4

输出结果:

script start => as1 start => as2 => prom1 => script end => as1.end => prom2 => setTimeout

解释

主=> 微 => 宏 async await 后的函数会随主任务执行

说明:有关async 和await 会在后续单独章节中进行讲解 案例 10

let promise = new Promise(function (resolved) { console.log('prom1'); resolved(); }).then(function() { console.log('prom2'); // 微任务1 }) async function as1() { console.log('as1 start'); await as2(); console.log('as1.end'); // 微任务2 } function as2() { console.log('as2'); } async function as3() { await promise; // 作用 后续js按照加入微任务顺序执行 console.log(8888); // 微任务3 } console.log('script start'); setTimeout(() => { console.log('setTimeout') }, 0); as1(); as3(); console.log('script end');

输出结果:

script start => as1 start => as2 => prom1 => script end => as1.end => prom2 => setTimeout

解释

主=> 微 => 宏 async await 紧跟await 后的函数会随主任务执行 但是await 下边一行的代码是作为微任务中调用 await promise 此时await 一个new好的promise 也是作为微任务中调用 prom1 script start => as1 start => as2 => script end =>prom2 => as1.end => 8888 => setTimeout



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3