大家都知道事件循环,我最初对事件循环的理解是:
当事件循环去执行微任务或者红任务时,互不影响,当其中一个微任务/宏任务回调函数被压到执行栈执行时,只要执行完就被弹出,那么回调函数内部代码出错了就会被直接弹出执行栈,但是事件循环不会停止,也就不回阻断其他事件回调函数执行。
但是,当我去上代码验证以后就发现了很有意思的现象
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("结束");
浏览器的执行结果是:
是不是跟我理解的一样,哈哈。
哎!!!!有意思的来了,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
执行结果是:
哈哈,是不是不一样,当异步回调函数内部出错了,那么整个事件循环就被阻断了,直接结束整个进程。
我再给你们看看起一个服务来跑这个代码:
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,先正常显示页面然后就崩了
在刷新一下页面,就崩了(其实这时候服务已经蹦停了)
好了,据我的观察得出的结论就是:
- 浏览器的事件循环里,异步回调方法(不管是微任务还是宏任务),内部报错了不会阻断事件循环,也不会影响其他异步事件回调方法的执行。
- nodejs的事件循环,异步回调方法(不管是微任务还是宏任务),内部报错了会阻断事件循环,会影响其他后面的异步事件回调方法的执行。