NodeJS EventLoop 和 Promise 关系简述

前言

今天去面试NodeJS的时候面试官问了关於Promise和Event Loop相关的问题
虽然平时操作经常用到但实际被问的时候还是解释的不太清楚
其中最让我印象深刻的问题是Promise用在哪里

我的回答是Promise是非同步操作,为了避免耗时的操作堵塞Process
结果被纠正说Promise应该是同步,觉得很怪所以回家整理了一下这方面的资料
其实这个问题已经有很多详解了,不过想说整理一遍,对自己的观念也比较清晰
如果有错欢迎指教


内文

Promise和Event Loop其他的文章应该有更详细的说明,这里不多做赘述。
直接上code:

var fs = require('fs');
function test(){
    console.log(1);
    let promise = new Promise((reslove,reject)=>{
        let data = fs.readFileSync(`${__dirname}/package.json`);
        reslove(6);
        console.log(2);
    });
    setTimeout(()=>{console.log("x")},0);
    console.log(3);
    promise.then((s)=>{
        console.log(s);
    });
    console.log(4);
    for(let i = 0; i<100;i++){
        let data = fs.readFileSync(`${__dirname}/package.json`);
    }
    
    return 5;
};
console.log(test());
function a(){
    return 0;
}
console.log(a());

输出结果:

1
2
3
4
5
0
6
x

发生了什麽

我们可以先从Event Loop的机制了解
大致上分为六个阶段:https://ithelp.ithome.com.tw/upload/images/20210105/20134017nVBP9YnzkA.png

这六个阶段根据官方概述:

1.定时器:本阶段执行已经被 setTimeout() 和 setInterval() 的调度回调函数。

2.待定回调:执行延迟到下一个循环迭代的 I/O 回调。

3.idle, prepare:仅系统内部使用。

4.轮询:检索新的 I/O 事件;执行与 I/O 相关的回调(几乎所有情况下,除了关闭的回调函数,那些由计时器和 setImmediate() 调度的之外),其余情况 node 将在适当的时候在此阻塞。

5.检测:setImmediate() 回调函数在这里执行。

6.关闭的回调函数:一些关闭的回调函数,如:socket.on('close', ...)。

根据上面的说明可以很清楚的了解到,基本上callback的执行阶段会落在第六步骤
因此当函式都Return完毕後才会轮到callback
所以在第四步骤输出123450
第六步骤输出6
而x是由於是setTimeout()的callback产生的行为
在使用的当下他会属於次轮循环
因为使用当下已经处於第四步骤,而setTimeout的callback属於第一步骤
於是等到次轮循环的时候才会将x显示出来


结论

至於为什麽面试官会说Promise会是同步操作的原因,事後打电话回去了解。
才知道原来他指的是建构Promise当下= ="(汗
但基本上Promise都是用於非同步操作,在大多数的事件结束後才去执行这个事情

这样的好处以网站来说,假设用户进行了一个转档的操作并且要显示在前端
可以先渲染前端页面,而转档这件大事,则是在渲染完前端後,再去执行

执行完毕後,再透过AJAX或是其他方式去更新用户的页面。

不必等到後端转档完毕 才一次把所有物品都丢到前端


<<:  咱研究出新的类阵列资料结构的说

>>:  是 POC 还是 RC? | 用 C# 实作 Windows 剪贴簿管理工具

Day09 - this&Object Prototypes Ch3 Objects - Contents - [[Put]]

[[Put]] 机制会在我们要赋予 object property 值的时候出现,[[Put]] 机...

第19天~dialog+Menu

dialog的DEMO 掀开新档 id命名为btnalert onClick从java档来加入 再来...

#8 - Reading & Writing Files (fs)

今天要学习的依然是 node.js 的core modules (就是内建的模组啦),主角是:fs ...

ESP32_DAY6 介绍Arduino

因为有使用到Arduino IDE,再加上今年以前的暑训都是在上Arduino,所以还是特别安排一天...

第28天:箭头函式与this()

在解析this的方式箭头函式与函式宣告不同,函式宣告是以呼叫时的方式来决定,而箭头函式在建立时就会决...