【发布时间】:2022-04-02 17:17:48
【问题描述】:
我知道阻塞事件循环是不好的,以及它的后果。但即使是原生 fs 模块也为某些目的提供了一些同步功能,例如使用 fs.readFileSync 的 CLI。
我想将以下异步等待代码转换为阻塞代码。
let value = undefined;
function setup() {
return new Promise((resolve) => {
setTimeout(() => {
value = "**value**";
resolve();
});
});
}
// need to convert below function to blocking
async function getValue() {
await setup();
return value;
}
console.log(await getValue()); // top level await OK
假设它是阻塞的,我们可以这样称呼它
getValue(); // without await or .then
我试过这样。但它不起作用。
function getValue() {
setup();
while (!value) {
// wait until we get value
}
return value;
}
console.log(getValue())
我怎样才能做到这一点?
(fs.readFileSync 是阻塞的。有什么方法可以使用 readFileSync 使用的技术)
编辑
相关主题:Convert asynchronous/callback method to blocking/synchronous method
【问题讨论】:
-
不,这是不可能的,因为“忙循环”会阻止事件队列上的任何事件被执行,这包括触发
setTimeout回调。那个回调——设置value——永远不会被执行。当你充分地为你的目的服务时拥抱异步编码模式。有了它,一切皆有可能。 -
您可以将所有代码包装在传递给 setup 的回调中,我猜很快就会陷入回调地狱。或者就像你在第一个例子中所做的那样使用 async await + top level await,你能解释为什么这不令人满意吗?
-
“
fs.readFileSync正在阻塞。有什么方法可以使用 readFileSync 使用的技术”不。readFilesync是同步的,因为它实际上是同步地工作,而不是像readFile那样异步地工作。您不能采用异步过程并使其在 JavaScript 代码中同步(在一般情况下)。您必须改为创建一个新的同步流程,这可能会也可能不会,具体取决于环境和您正在执行的流程。例如,在极端情况下,您可以生成一个单独的进程来完成工作...... -
...并通过
execSync等同步等待它。但是... :-) -
我知道在这里的 cmets 中经常提到“XY 问题”,但这看起来像 an XY problem。
标签: javascript node.js asynchronous