在.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); } });