【发布时间】:2021-03-22 01:01:23
【问题描述】:
目前,我定义了两个函数如下:
function getLock() {
let promise, isPending;
if (Math.random() > 0.5) {
promise = new Promise((resolve, reject) => setTimeout(resolve, 1000));
isPending = true;
} else {
promise = Promise.resolve();
isPending = false;
}
return [promise, isPending];
};
function waitForLock() {
const lockAndIsPending = getLock();
const lock = lockAndIsPending[0];
const isPending = lockAndIsPending[1];
if (!isPending) {
return lock;
} else {
return lock.then(waitForLock);
}
}
waitForLock().then(() => console.log("done"));
这当然只是为了演示。作为现实世界应用程序的必需品,getLock 总是需要返回一个 Promise。 另外,锁被释放一次后,必须检查它是否仍然被释放(lock.then(waitForLock)),因为实际的释放条件(这里由Math.random()建模)可能同时由于异步而发生变化。这引入了递归。
我当前的代码工作正常:waitForLock() 最终会返回,因为它会在某个时候发生getLock 返回isPending=false,满足终止条件。
但我的目标是摆脱 isPending 作为额外的返回变量。将来,getLock 应该只返回一个承诺。不幸的是,无法检查给定的承诺是否已经解决(参见here),因此我无法在waitForLock 中“计算”isPending。那么如何相应地更改waitForLock?
编辑
目标是能够为getLock 使用任何Promise-returning 函数,而对返回或解析值没有特殊限制。所以,如果可能的话,逻辑应该都在waitForLock,而不是getLock。
【问题讨论】:
-
你为什么不直接
await getLock()? -
这不会改变递归问题,对吗?我仍然需要决定是否第二次拨打
waitForLock。 -
我不这么认为,请看下面我的回答
-
waitForLock不是您正在寻找的函数,它返回一个关于何时释放锁的承诺? -
是的,当前的实现工作,但它依赖于我想摆脱的“附加信息”(即
isPending变量)。
标签: javascript asynchronous recursion promise