Javascript Node js对10个异步调用的聚合响应
我们有一个需求,我们希望基于(contentId[]=1&contentId[]=2…等)的查询参数数组构建api调用,然后进行异步调用,将id附加到api端点,例如 根据响应,我们需要聚合内容并使用字段contentId包装内容,响应代码是我们在访问各个api端点时收到的Javascript Node js对10个异步调用的聚合响应,javascript,node.js,promise,Javascript,Node.js,Promise,我们有一个需求,我们希望基于(contentId[]=1&contentId[]=2…等)的查询参数数组构建api调用,然后进行异步调用,将id附加到api端点,例如 根据响应,我们需要聚合内容并使用字段contentId包装内容,响应代码是我们在访问各个api端点时收到的 { { "contentd": "1", "responsecode": 200, "messsage": "", content{ } } { "contentd": "2", "responsecode": 20
{
{ "contentd": "1",
"responsecode": 200,
"messsage": "",
content{
}
}
{ "contentd": "2",
"responsecode": 200,
"messsage": "",
content{
}
...
}
我们正在用承诺来做同样的事情。我曾经承诺如下
Promise.all(req.query.contentId
.map(function (contentId) {
console.log('processing the content id'+contentId);
return getContent(contentId);
}))
.then(function (all_content) {
//convert each resolved promised into JSON and convert it into an array.
res.json(all_content.map(function (content) {
return JSON.parse(content)
}));
})
.catch(function(rej) {
//here when you reject the promise
console.log("404 received"+rej);
}) ;
} catch (e) {
res.send(e.message);
}
});
// this is the function that makes the call to the backend. Note usage of request promise
function getContent(contentId) {
console.log('content id received to fetch the content'+contentId);
var options = {
uri: 'http://xxxxx/api/content/'+contentId,
headers: {
'Authorization': 'Basic YWRtaW46YWRtaW4='
},
qs: {
_format: 'json'
}
};
return rp(options);
}
问题-我们面临的问题是,当我们得到http状态码为200时,调用结果很好。但是,对于http状态代码404(未找到),处理未完成。它似乎失败得很快
另外,在JSON.parse中处理内容响应时,如何插入自己的响应、状态字段。谢谢
return getContent(contentId);
在这里,你把诺言还给诺言。因此,如果承诺失败,它将触发承诺。所有捕获和所有路线都失败。所以我们需要早点抓到,就在这里:
return getContent(contentId).catch( e => e);
这意味着,如果出现错误,则继续执行错误作为结果。由于JSON.parse将失败,因此您可以返回一个JSON字符串:
return getContent(contentId).catch( e => '{"error":500}');
关于第二个问题: 您可能希望为返回的结果分配其他属性:
return Object.assign( JSON.parse(content), {
what: "ever"
});
如果你读到了
Promise.all()
,它就是这么做的。如果您通过的任何承诺被拒绝,它会立即拒绝整个promise.all()
promise,并且您不会得到其他结果
如果您想要所有其他结果,您必须提前捕获任何拒绝,以便Promise.all()
永远不会看到它们,或者使用不同的方法跟踪所有承诺,以获得所有响应,无论是否拒绝
通过这样做,您可以更早地捕获拒绝,以“隐藏”它的形式Promise.all()
,并且您还必须跳过传递的任何错误对象的JSON.parse()
Promise.all(req.query.contentId
.map(function (contentId) {
console.log('processing the content id'+contentId);
// catch errors here and make the resolved value be the error object
// so Promise.all() processing continues on the other requests
return getContent(contentId).catch(e => e);
}))
.then(function (all_content) {
//convert each resolved promised into JSON and convert it into an array.
res.json(all_content.map(function (content) {
// make sure we don't try to parse things that are already objects
// like error objects
if (typeof content !== "string") {
return content;
} else {
return JSON.parse(content);
}
}));
}).then(function(results) {
// remove any error objects
// and probably log them to so they aren't just silently eaten
return results.filter(item => !(item instanceof Error));
})
然后,稍后在使用此结果数组时,需要跳过结果中的任何错误对象
或者,您可以将结果生成某种不影响下游处理的无操作结果,或者您可以构建一个不同的数组,将所有错误结果过滤掉
而且,如果您想要一些预先编写的代码只获取所有响应(包括错误结果),通常称为Promise.solite()
。有几种Promise.solite()
的实现,您可以在这里使用:
另外,在JSON.parse中处理内容响应时,如何插入自己的响应、状态字段 您可以更改此设置:
return JSON.parse(content);
对这样的事情:
let obj = JSON.parse(content);
obj.someOtherProp = 'myvalue';
return obj;
我认为
getContent(contentId).catch(e=>e)
将导致后面的JSON.parse()
抛出,因为您将向它传递一个错误对象,而不是可解析的JSON字符串。@user1643003-这是否回答了您的问题?