我们目前正在使用bluebird
v2.9.8
,无法升级到v3
以获得兼容性(目前,但可能没有解决方案)。
我们过去曾使用.settle()
,但我们遇到的情况是,我们有一组users
,映射到promises
,我们需要确认特定字段是否为true
。
如果只有false
的案例,那么就没有必要继续了。如果它们都是true
,那就意味着我们已经执行了所有promises
。
Promise.settle()
将执行所有操作,等待所有操作完成。
同样,我们的目标是在获得false
后立即中断。
结果是另外一段代码正在调用额外的Promise
来从db获取更多信息。因此,重写为使用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();
});
这确实允许我们在第一次拒绝后中断,但无论如何已经开始的任何其他数据库调用都已完成。
这将有效,并允许我们更快地将响应返回给客户端,但仍然留下一些浪费的处理。
答案 0 :(得分:1)
使用Promise.all()
代替Promise.settle()
。
Promise.all()
将在传递的第一个承诺拒绝时结束,并且不会等待其余的承诺。因此,您可以测试您的情况然后拒绝,然后Promise.all()
也会立即拒绝。
Promise.settle()
将等待所有请求完成,无论结果如何。
如果您展示了一些代表性的代码,我们可以更具体地帮助您。
以下是一个例子:
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);
}
});