JavaScriptBluebird承诺:并发API请求的体系结构
我正在寻求建筑方面的建议。在一个普通的环境中使用Bluebird Promises(这里是node.js服务器端),我打算进行许多并发API调用,聚合所有结果并响应客户端。示例(伪)代码: 现在我不知道如何确保:JavaScriptBluebird承诺:并发API请求的体系结构,javascript,promise,bluebird,Javascript,Promise,Bluebird,我正在寻求建筑方面的建议。在一个普通的环境中使用Bluebird Promises(这里是node.js服务器端),我打算进行许多并发API调用,聚合所有结果并响应客户端。示例(伪)代码: 现在我不知道如何确保: 同时激发所有请求(不是按顺序以减少 响应时间) 收到所有API请求的响应后立即响应客户端 如果一个API请求因任何原因而失败,则不会拒绝整个承诺链,从而“丢失”另一个API响应数据 我在Bluebird Promise网站上查看了合适的收藏,但似乎没有一个完全符合上面列出的要求。有什么
我在Bluebird Promise网站上查看了合适的收藏,但似乎没有一个完全符合上面列出的要求。有什么建议吗?一种方法是使用
reflect
调用
var Promise= require('bluebird');
Promise.props({
"wrapper1": someasync(1).reflect(),
"wrapper2": someasync(0).reflect(),
"wrapper3": someasync(1).reflect()
})
.then(function(results) {
Object.keys(results).forEach(function(key) {
if (results[key].isRejected()) {
console.log(key + " failed.", results[key].reason());
} else {
console.log(key + " successed", results[key].value());
}
});
});
function someasync(t) {
if (t===0) return Promise.reject('some err');
else return Promise.resolve(true);
}
其结果如下:
wrapper1 successed true
wrapper2 failed. some err
wrapper3 successed true
如果需要,可以手动推荐API方法,例如:
var p1 = new Promise(function(resolve, reject) {
wrapper1.getResultsFromAPI1(searchquery, function(err, data) {
if (err) reject(err);
else resove(data);
});
});
但是既然您使用的是BlueBird库,那么就可以使用promisify.promisify
,这样就可以避免将方法包装成promises的样板代码。例如:
var getResultsFromAPI = Promise.promisify(wrapper1.getResultsFromAPI1);
var p1 = getResultsFromAPI(searchquery);
而且,如果您想推广API的所有方法,可以使用Promise.promisifyAll
。例如:
var wrapper1 = Promise.promisifyAll(require('my-api'));
// then, all the wrapper1 methods are already wrapped into a Promise
var p1 = wrapper1.getResultsFromAPI1(searchquery);
因此,在将所有方法转化为承诺后,您可以使用承诺。解决来实现您想要的:查看哪些承诺得到了履行,哪些承诺被拒绝:
exports.getAllData = function(searchquery, cb) {
/* Don't forget to promisify all the API methods firstly */
var results;
var p1 = wrapper1.getResultsFromAPI1(searchquery);
var p2 = wrapper2.getResultsFromAPI2(searchquery);
var p3 = wrapper3.getResultsFromDataBase(searchquery);
Promise.settle([p1, p2, p3]).then(function(arr) {
arr.forEach(function(res, index) {
if (res.isFulfilled()) { // check if the Promise was fulfilled
results += res.value(); // the Promise's return value
}
else if (res.isRejected()) { // check if the Promise was rejected
console.log(res.reason()); // do something with the error
}
});
cb(null, results);
});
}
承诺。结算
应该可以。如果我错了,请纠正我,但结算仅在承诺数组中的所有项都已结算后才进行结算。一旦有一项(在我的例子中是一个API调用)失败,整个承诺链就会失败。这不是我需要的。@IgorP<代码>承诺。当传递的承诺之一失败时,所有
都将失败<代码>承诺。结算
将为您提供一个数组,其中包含拒绝承诺和解决承诺的信息。因此,您将解决您的问题,看看是否所有请求都已完成。哦,好的。我当时一定是误解了网上的参考资料。我试试看。谢谢=)@Bergi请给我一个评论
var wrapper1 = Promise.promisifyAll(require('my-api'));
// then, all the wrapper1 methods are already wrapped into a Promise
var p1 = wrapper1.getResultsFromAPI1(searchquery);
exports.getAllData = function(searchquery, cb) {
/* Don't forget to promisify all the API methods firstly */
var results;
var p1 = wrapper1.getResultsFromAPI1(searchquery);
var p2 = wrapper2.getResultsFromAPI2(searchquery);
var p3 = wrapper3.getResultsFromDataBase(searchquery);
Promise.settle([p1, p2, p3]).then(function(arr) {
arr.forEach(function(res, index) {
if (res.isFulfilled()) { // check if the Promise was fulfilled
results += res.value(); // the Promise's return value
}
else if (res.isRejected()) { // check if the Promise was rejected
console.log(res.reason()); // do something with the error
}
});
cb(null, results);
});
}