JavaScript的事件循环原理(Event Loop)

一个悲伤的故事

我是19应届的,但是秋招还是没拿到Offer,也许是我期望太高,要求太高,亦或许是其他。。。现在打算好好再学习一些更深层次的知识,决战春招,舍友拿了58的17K的offer,人比人得死(虽然现在秋招还没结束,但是好的公司没几个在招人了)


那么我们进入正题吧,用一段代码来说明这个事件循环(Event Loop)的原理:

//这里我用花括号包起来防止污染
{
    const log = console.log;
    log('代码开始');//这里是运行环境代码,就是Context Script
    
    new Promise((resolve, reject) => {
    	//这里的代码相当于Promise的构造函数,你new之后,这里会直接执行
        log("微任务A构造执行");
        resolve();
    }).then(() => {
    	//then是异步回调,我假设你们都懂Promise的哈
        log("微任务A回调");
    });
    log("微任务A已添加");
    
    setTimeout((args) => {//setTimeout的回调函数可以拿到setTimeout的第三个参数(数组)
        log('宏任务X执行,,,', args);
        new Promise((resolve, reject) => {
            log("微任务B构造执行");
            resolve();
        }).then(() => {
            log("微任务B回调");
        });
        log("微任务B已添加");
    }, 0, [1, 2, 3, 4]);//这个比较冷门,setTimeout的第三个参数,一个数组,这里提一下而已。。。
    log("宏任务X已添加");

    
    setTimeout((args) => {
        log('宏任务Y执行,,,', args);
    }, 0, [1, 2])
    log("宏任务Y已添加");
}

输出结果:

代码开始
微任务A构造执行
微任务A已添加
宏任务X已添加
宏任务Y已添加
微任务A回调
宏任务X执行,,, (4) [1, 2, 3, 4]
微任务B构造执行
微任务B已添加
微任务B回调
宏任务Y已添加
宏任务Y执行,,, (2) [1, 2]


理解

第一次运行	
运行上下文代码,比如上面的    log('代码开始');
如果微任务队列不为空,运行全部微任务

第二次运行
取一个宏任务(可能是setTImeout或者setTinterval)
这个宏任务完成后,如果微任务队列不为空,运行全部微任务

之后的运行和第二次运行相同

》简图
JavaScript的事件循环原理(Event Loop)