当使用第三方库提供的异步函数或可观察对象时,例如Cloud Firestore,在需要等待某个过程完成但又不想在回调中嵌套回调或者冒着陷入无限循环的风险时,我发现下面所示的
waitFor
方法(TypeScript编写,但你明白我的意思……)非常有用。
该方法有点类似于
while (!condition)
睡眠循环,但它是异步执行的,并且会在一定时间间隔内反复进行完成条件测试,直到为真或超时。
export const sleep = (ms: number) => {
return new Promise(resolve => setTimeout(resolve, ms))
}
export const waitFor = async function (interval: number, timeout: number,
booleanFunction: Function): Promise<boolean> {
let elapsed = 1;
if (booleanFunction()) return true;
while (elapsed < timeout) {
elapsed += interval;
await sleep(interval);
if (booleanFunction()) {
return true;
}
}
return false;
}
假设您的后端有一个长时间运行的进程,您希望在执行其他任务之前完成它。例如,如果您有一个函数来计算账户列表的总数,但是您想在计算之前从后端刷新账户,您可以像这样操作:
async recalcAccountTotals() : number {
this.accountService.refresh();
if (this.accounts.dirty) {
let updateResult = await waitFor(100,2000,()=> {return !(this.accounts.dirty)})
}
if(!updateResult) {
console.error("Account refresh timed out, recalc aborted");
return NaN;
}
return ...
}