如何在 JavaScript 中将此算法编码为 promise?
// condition: some situation that is not true
// interval: period to wait before trying again
// retriesAllowed: maximum number of retries to make before aborting
// retriesMade: number of retries made so far
while() {
if (condition) return true; // indicates success
if (retriesMade < retriesAllowed) return false; // or throw an exception
++retriesMade;
wait(interval);
}
这是行不通的,因为它实际上并没有在继续之前等待检查结果为真或假:
var check = () => {
if (condition) return true; // indicates success
if (retriesMade < retriesAllowed) return false; // or throw an exception
++retriesMade;
setTimeout(check,interval)
}
check();
最佳答案
This doesn't work, since it doesn't actually wait for the check to resolve to true or false before moving on.
其中一部分可能是失败/退出条件似乎是相反的,因此它可能总是在第一轮检查条件
之后退出:
// retriesMade starts at 0, which is likely already less-than retriesAllowed
if (retriesMade < retriesAllowed) return false;
// probably should be
if (retriesMade >= retriesAllowed) return false;
除此之外,没有等待是通过异步操作设计的,例如 setTimeout()
等待给定的延迟间隔。周围的代码将始终继续执行而不等待它们的结果。
与其期望他们等待,您需要建立一种方法,以便在流程实际完成时得到通知,并根据该信息继续进行。 Promises 是一种选择。
Side note: A thorough explanation of the behavior and other options are provided in "How do I return the response from an asynchronous call?"
有了它们,它们提供了 resolve()
和 reject()
,而不是使用 return
或 throw
> 在调用时分别表示成功或失败的函数。它们的 .then()
和 .catch()
方法可用于设置延续。
var tries = new Promise((resolve, reject) => {
var retriesMade = 0;
var interval = 1000;
var check = () => {
if (condition) { resolve(); }
if (retriesMade >= retriesAllowed) { reject(); }
++retriesMade;
setTimeout(check, interval);
});
check();
});
tries.then(
() => console.log('success'),
() => console.log('failure')
);
还有一个更彻底地使用 Promises 的替代版本,包含函数中的迭代 (untilLimited
) 以及允许条件 (exitUpon
) 是异步的,如果需要的话。
function delay(milliseconds) {
return new Promise(function (resolve) {
setTimeout(resolve, milliseconds);
});
}
function untilLimited(limit, waitTime, exitUpon) {
return Promise.resolve()
.then(exitUpon)
.then(result => {
if (result) return true;
if (!(--limit > 0)) return Promise.reject('Limit exceeded.');
return delay(waitTime)
.then(() => untilLimited(limit, waitTime, exitUpon))
});
}
untilLimited(5, 500, () => false /* condition */)
.then(
(result) => console.log('success', result),
(result) => console.log('failure', result)
);
关于Javascript: promise 等待条件或在尝试次数后中止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39679670/