在.settle()(或等价的)中打破一系列的Promise

目前我们正在使用bluebird v2.9.8 ,无法升级到v3兼容(现在,但可能没有解决scheme)。

过去我们已经使用了.settle() ,但是我们遇到了一个users集合映射到promises ,我们需要确认一个特定的字段是否为true

如果只有一个false情况,那就没有必要继续了。 如果他们都是true ,那就意味着我们已经执行了所有的promises

Promise.settle()将执行所有,等到所有完成。

再一次,我们的目标是一旦我们得到一个false中断。


原来的代码额外的一块是调用额外的Promise以获得更多的信息从数据库。 所以,重写使用Promise.all()

 var accessPromises = users.map(function (user) { return new Promise(function(resolve, reject) { if (user.userId == matchingUserId) { return resolve(true); } else if (user.type && user.type == matchingType) { return resolve(true); } else { // See if this user is one of your connections DB.getAdditionalUserInfo() .then(function (additionalUserInfo) { if (additionalUserInfo.a == user.userId) return resolve(true); else return reject(false); }) .catch(function (err) { return reject(false); }); } }); }); Promise.all(accessPromises).then(function (accessResults) { if (accessResults.every(result => result) res.ok(); else res.notFound(); }) .catch(function (err) { res.notFound(); }); 

这确实允许我们在第一次拒绝之后中断,但是任何已经开始的额外数据库调用总是完成的。

这将起作用,并使我们能够更快地将响应反馈给客户端,但仍会留下一些浪费的处理。

使用Promise.all()而不是Promise.settle()

Promise.all()将在第一个承诺通过时完成拒绝,不会等待其余的。 所以,你可以testing你的条件,然后拒绝,然后Promise.all()也会立即拒绝。

另一方面, Promise.settle()将等待所有请求完成,而不pipe结果如何。

如果你展示了一些代表性的代码,我们可以更具体地帮助你。

这是一个制造的例子:

 function getUser(name) { // code that returns a promise whose fulfilled value is a user object } function getUserTestField(name) { return getUser(name).then(function(user) { if (!user.someField) { return Promise.reject({status: false}); } else { return user; } }, function(err) { return Promise.reject({errCode: err}); }); } var promises = ["bob", "ted", "alice"].map(function(name) { return getUserTestField(name); }); Promise.all(promises).then(function(users) { // all users had field set to true }, function(err) { if (err.status === false) { // at least one user has the field set to false } else { // some other type of error here console.log(err.errCode); } });