我在TypeScript / JavaScript中有一个漫长而复杂的异步过程,分布在许多库和函数中,当它最终完成接收和处理所有数据时,调用函数processComplete()
来表示它已完成:
processComplete(); // Let the program know we're done processing
现在,该功能看起来像这样:
let complete = false;
function processComplete() {
complete = true;
}
为了确定流程是否完整,其他代码使用超时或process.nextTick
并在循环中反复检查complete
变量。这是复杂而低效的。
我想让各种async
函数只使用await
等待并在流程完成时被唤醒:
// This code will appear in many different places
await /* something regarding completion */;
console.log("We're done!");
如果我在C中用Windows编程,我会使用event synchronization primitive,代码看起来像这样:
Event complete;
void processComplete() {
SetEvent(complete);
}
// Elsewhere, repeated in many different places
WaitForSingleObject(complete, INFINITE);
console.log("We're done!");
在JavaScript或TypeScript中,不是将布尔complete
值设置为true,而是processComplete
可以做什么来唤醒使用await
等待的任意数量的函数?换句话说,如何使用await
和async
或Promise
来实现事件同步原语?
答案 0 :(得分:1)
此模式非常接近您的代码:
const processComplete = args => new Promise(resolve => {
// ...
// In the middle of a callback for a async function, etc.:
resolve(); // instead of `complete = true;`
// ...
}));
// elsewhere
await processComplete(args);
console.log("We're done!");
更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise。
答案 1 :(得分:1)
这实际上取决于您在此方案中使用“其他代码”的含义。听起来您想要使用delegation pattern或observer pattern的某些变体。
一种简单的方法是利用JavaScript允许您存储一系列函数的事实。您的processComplete()
方法可以执行以下操作:
function processComplete(){
arrayOfFunctions.forEach(fn => fn());
}
在其他地方,您可以在其他代码中创建函数,以便在流程完成时完成所需的操作,并将这些函数添加到arrayOfFunctions
。
如果您不希望这些不同的代码部分如此紧密地连接,您可以设置一个完全独立的代码部分作为通知中心。然后,您可以让其他代码告知通知中心它希望在流程完成时收到通知,并且您的processComplete()
方法只会告知通知中心流程已完成。
另一种方法是use promises。
答案 2 :(得分:0)
我在TypeScript / JavaScript中有一个漫长而复杂的异步过程,分布在许多库和函数中
然后确保异步进程的每个位都返回其部分结果的promise,以便您可以链接到它们并将它们组合在一起或await
它们。
当它最终完成接收并处理其所有数据时,调用函数
processComplete()
以表示它已完成
不应该。启动进程的函数应该返回一个promise,当进程完成时,它应该履行这个承诺。
如果你不想正确地宣传整个过程中的每一点,因为它过于繁琐,你可以做到
function startProcess(…);
… // do whatever you need to do
return new Promise(resolve => {
processComplete = resolve;
// don't forget to reject when the process failed!
});
}
在JavaScript或TypeScript中,不是将布尔
complete
值设置为true,而是processComplete
可以做什么来唤醒使用await
等待的任意数量的函数?< / p>
如果他们已经await
承诺的结果,那么就没有其他事情需要做了。 (等待的承诺内部已经有这样的旗帜)。它真的只是在做
// somewhere:
var resultPromise = startProcess(…);
// elsewhere:
await resultPromise;
… // the process is completed here
如果你需要的只是同步你的任务,你甚至不需要以有用的结果履行承诺,但你真的应该这样做。 (如果没有他们正在等待的数据,他们还在等什么?)