摆脱 Javascript 中的拒绝承诺递归

Rad*_*ina 5 javascript recursion

假设我在下面有这个功能:

var a = 0;
function test () {
  return new Promise(function (resolve, reject) {
    a++;
    if (a < 10) {
      test()
      reject(a)
    } else {
      resolve(a)
    }
  })
}

test().then(function (a) {
  console.log('resolve', a)
}).catch(function (a) {
  console.log('reject', a)
})
Run Code Online (Sandbox Code Playgroud)

它打印:

拒绝 10

我希望它会打印reject 1 ... 10.

我怎样才能做到这一点?

T.J*_*der 4

您只看到一个结果的原因是没有任何内容使用或报告递归调用的结果test,只有第一个结果。您需要移动报告逻辑和增量逻辑:

var a = 0;
function test () {
    doOne(a++).then(function (a) {
    //     ^^
      console.log('resolve', a)
      if (a < 10) {
        test(); // Keep going
      }
    }).catch(function (a) {
      console.log('reject', a)
      if (a < 10) {
        test(); // Keep going
      }
    })
}

function doOne (a) {
  return new Promise(function (resolve, reject) {
    if (a < 10) {
      reject(a)
    } else {
      resolve(a)
    }
  })
}

test()
Run Code Online (Sandbox Code Playgroud)

但请注意,除非您更改if (a < 10)支票,否则它resolve 10不会显示reject 10在最后。

还值得注意的是,除了对承诺结算处理程序的调用之外,代码中没有任何内容是异步的(因为这些调用始终是异步的)。Promise 用于报告异步流程的完成情况和结果。没有理由将它们用于同步进程。

或者这是另一种方法,避免使用代码全局的变量,等待前一个承诺解决,然后再继续下一个承诺(这可能是也可能不是您想要的),使得可以知道整体操作何时完成已完成,并避免重复a < 10逻辑:

function test(a) {
    return doOne(a).then(function (a) {
      console.log('resolve', a)
    }).catch(function (a) {
      console.log('reject', a)
      return test(a + 1);
    });
}

function doOne(a) {
  return new Promise(function (resolve, reject) {
    if (a < 10) {
      reject(a)
    } else {
      resolve(a)
    }
  })
}

test(0)
.finally(() => {
  console.log("Done");
});
Run Code Online (Sandbox Code Playgroud)

请注意,这依赖于这样一个事实:我们只想在doOne拒绝其承诺时继续。

  • 是的,目前还不清楚他们想要什么,但是“test”尽管做了一些异步操作(并且不等待递归调用)但没有返回承诺,看起来很危险。 (2认同)