Q.allSettled 曾经失败过吗?

Does Q.allSettled ever fail?

我在单元测试的某些地方看到函数 returns 来自函数调用的 q.allSettled() promise 并且 .fail 附在 promise 上。但是 .allSettled 会调用 .then 即使 some/all 承诺被拒绝。

这是一个例子:

function someFunctionToTest(){
  var aRejectedDeferred = Q.defer();
  var anotherRejectedDeferred = Q.defer();
  var aResolvedDeferred = Q.defer();

  aRejectedDeferred.reject(new Error("I'm aRejectedPromise"));
  anotherRejectedDeferred.reject(new Error("I'm anotherRejectedPromise"));
  aResolvedDeferred.resolve({awesome:"I'm aResolvedPromise"});

  return Q.allSettled([aRejectedDeferred.promise,anotherRejectedDeferred.promise, aResolvedDeferred.promise])
}

it('should never fail', function(done) {

  someFunctionToTest()
      .then(function (data) {
        should.equal(data[0].state,'rejected');
        should.equal(data[1].state,'rejected');
        should.equal(data[2].state,'fulfilled');
        // throw(new Error('I will trigger fail!!!'));
        done();
      })
      .fail(function (err) {
        done(err);
      });
});

能否提供一些触发 .fail 的示例?

Q.allSettled 不能失败。请参阅 Q API,上面写着

Returns a promise that is fulfilled with an array of promise state snapshots, but only after all the original promises have settled, i.e. become either fulfilled or rejected.

很明显,无论 allSettled 中的什么承诺,您仍然会得到已解决的承诺。

在您的特定情况下,.then 语句可能会因为例如下一行

should.equal(data[0].state,'rejected');

这可能会抛出断言异常,导致失败,您可以捕获它,运行 done(); 这是告诉测试工具异步请求已完成的方式。但这只是一个猜测。 Q.allSettled 本身不会失败。

您可能需要考虑两件事:

  1. Q.allSettled 没有 fail 函数,它只适用于 done() ,它以 promise 状态作为参数。您应该检查这些状态,看看 promise 是 fulfilled 还是 rejected。但是 Q.all 有一个 then 和一个 fail 函数,您可能想使用但没有参数将传递给 then,因此不知道状态。
  2. 如果您在每个承诺中手动捕获错误(即为每个承诺实现 fail() 函数),状态将始终为 fullfiled,因此在使用 Q.all 或者Q.allSettled,要么不捕获promise中的错误,要么捕获后再次抛出!