浏览器事件循环和nodejs事件循环,分享一个很有意思的案例,也请大佬指点一下

80 阅读2分钟

大家都知道事件循环,我最初对事件循环的理解是:

当事件循环去执行微任务或者红任务时,互不影响,当其中一个微任务/宏任务回调函数被压到执行栈执行时,只要执行完就被弹出,那么回调函数内部代码出错了就会被直接弹出执行栈,但是事件循环不会停止,也就不回阻断其他事件回调函数执行。

但是,当我去上代码验证以后就发现了很有意思的现象

1.浏览器中,跟我想的一样,请看代码:

test.html

console.log("开始");
setTimeout(() => {
    new Promise(res => {
        res("嘿嘿2")
    }).then(res => {
        console.log('res2: ', res);
    })
    console.log("我是第一个", b);
}, 1);
setTimeout(() => {
    console.log("我是第二个");
}, 100);

new Promise(res => {
    res("嘿嘿")
}).then(res => {
    console.log('res: ', res);
})
console.log("结束");
浏览器的执行结果是:

image.png

是不是跟我理解的一样,哈哈。

哎!!!!有意思的来了,nodejs的执行结果不一样

还是一样的代码:

test.js

console.log("开始");
setTimeout(() => {
    new Promise(res => {
        res("嘿嘿2")
    }).then(res => {
        console.log('res2: ', res);
    })
    console.log("我是第一个", b);
}, 1);
setTimeout(() => {
    console.log("我是第二个");
}, 100);

new Promise(res => {
    res("嘿嘿")
}).then(res => {
    console.log('res: ', res);
})
console.log("结束");

在控制台运行:node test.js

执行结果是:

image.png

哈哈,是不是不一样,当异步回调函数内部出错了,那么整个事件循环就被阻断了,直接结束整个进程。

我再给你们看看起一个服务来跑这个代码:

const http = require("http");
const server = http.createServer();
server.on("request", (req, res) => {
    console.log("开始");
    setTimeout(() => {
        console.log("我是第一个", b);
        new Promise(res => {
            res("嘿嘿2")
        }).then(res => {
            console.log('res2: ', res);
        })
    }, 1);

    setTimeout(() => {
        console.log("我是第二个");
    }, 100);

    new Promise(res => {
        res("嘿嘿")
    }).then(res => {
        console.log('res: ', res);
    })
    console.log("结束");
    res.setHeader('Content-Type', 'text/html;charset=utf-8');
    //res.write()表示向客户端输出的方法
    res.write("hello world,你好nodejs")
    //res.end()每次响应完,需要调用此方法 来结束响束
    res.end();
})

server.listen(3000, () => {
    console.log("服务器启动成功,3000");
})

页面访问localhost:3000,先正常显示页面然后就崩了

image.png

image.png 在刷新一下页面,就崩了(其实这时候服务已经蹦停了)

image.png

好了,据我的观察得出的结论就是:

  1. 浏览器的事件循环里,异步回调方法(不管是微任务还是宏任务),内部报错了不会阻断事件循环,也不会影响其他异步事件回调方法的执行。
  2. nodejs的事件循环,异步回调方法(不管是微任务还是宏任务),内部报错了会阻断事件循环,会影响其他后面的异步事件回调方法的执行。