Javascript: promise 等待条件或在尝试次数后中止

标签 javascript promise

如何在 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(),而不是使用 returnthrow > 在调用时分别表示成功或失败的函数。它们的 .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/

相关文章:

javascript - Google map + Google 本地搜索根据英国邮政编码生成纬度/经度

Javascript - 如何使用不在同一范围内的 onClick 事件监听器清除回调内的 setInterval

r - 什么是 parent promise ?

javascript - 为什么创建一个新的繁琐连接会使我的程序无法完成?

javascript - 使用 setTimeout 进行基本的 JavaScript promise 测试

javascript - 获取 jQuery 选择器的数组索引

javascript - jquery,将多个值附加到一个隐藏的输入

javascript - 如何对 JavaScript 表(升序或降序)进行排序,该表是某些 SQL 操作表的结果?

promise - 不发送任何新 Action 的 redux-observable 史诗

javascript - 异步谷歌分析 [Javascript 高尔夫]