javascript - async/await 会阻塞事件循环吗?
问题描述
我正在阅读Node.js 指南中的 Don't Block the Event Loop。有句话说:
你应该确保你永远不会阻塞事件循环。换句话说,您的每个 JavaScript 回调都应该快速完成。这当然也适用于你
await
的,你Promise.then
的,等等。
我开始想,如果对我正在await
处理的数据库的某些 API 调用需要一些时间来解决,这是否意味着我已经用该await
调用阻塞了事件循环?
之后,我开始测试一些自己编写的代码,但测试后我仍然不清楚阻塞是如何await
工作的。下面是一些测试代码:
假设我正在使用 express 进行测试。我理解为什么在这种情况下对路由进行 2 次 API 调用会/test
阻塞事件循环。
function someHeavyWork() {
// like calling pbkdf2 function
}
app.get('/test', (req, res) => {
someHeavyWork();
res.json(data);
});
但在这种情况下不会发生这种情况。
function fakeDBCall() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(data);
}, 5000)
})
}
app.get('/test', async (req, res) => {
const data = await fakeDbCall();
res.json(data);
})
这可能是因为我对阻塞在async/await
.
解决方案
与看起来相反,await
不会阻塞。它只是承诺之上的语法糖。没有任何东西被阻塞;允许代码同步可能看起来很阻塞,但这只是对承诺的糖分。例如,这可能看起来是同步的:
const response = await fetch(…);
const json = await response.json();
const foo = JSON.parse(json); // Using json here, even though my request was async!
但事实并非如此。一旦你脱糖,你得到的只是承诺,它们是非阻塞的:
fetch(…)
.then(response => response.json())
.then(json => {
const foo = JSON.parse(json);
});
如果await
被阻塞,那将是绝对灾难性的。JavaScript 运行时通常是单线程的。这意味着只要您发出请求或其他异步操作(例如使用文件系统),用户交互和其他进程就会停止。在相关的说明中,这与动态导入一起是反对顶级的主要论据await
推荐阅读
- java - 如何在 Java 中创建目录?
- python - 评估 x 在 range(n) 内的时间复杂度是多少 **Python3**
- ocaml - OCaml中列表上的相互递归的语法错误
- nlp - Word2Vec 的功能是否相互独立?
- python - ValueError:错误的预期数组形状 - Keras 神经网络
- javascript - 如何为引导模式一起触发 2 个事件?
- ios - 重新排序时在 tableviewcell 上添加阴影
- javascript - 如何将 co.wrap 与生成器一起使用
- ruby-on-rails - jsonb 保存数组列 jsonb postgres rails
- python - 使用 Lambda 从 base64 上传 s3