我正在处理一个项目,该项目涉及向不同的API发出多个HTTP GET请求,每个API都需要来自最后一个的信息。我试图避免嵌套 - 卡拉加和反地狱,并一直试图让它与async
模块一起使用。
这就是我需要做的:我有一个1..n课程标识符(['2014/summer/iat/100/d100', '2014/spring/bisc/372/d100']
)的数组。对于数组中的每个课程,我需要通过HTTP GET获取其课程大纲。
结果大纲看起来像这样:
{
"info": {
"nodePath": "2014/spring/bisc/372/d100",
"number": "372",
"section": "D100",
"title": "Special Topics in Biology",
"term": "Spring 2014",
"description": "Selected topics in areas not currently offered...",
"name": "BISC 372 D100",
"dept": "BISC",
},
"instructor": [
{
"lastName": "Smith",
"commonName": "Frank",
"phone": "1 555 555-1234",
"email": "franksmith@school.edu",
"name": "Frank Smith",
"roleCode": "PI"
},
{
"lastName": "Doe",
"commonName": "John",
"phone": "1 555 555-9876",
"email": "johndoe@school.edu",
"name": "John Doe",
"roleCode": "PI"
}
]
}
(省略了一堆不相关的字段)
每个大纲对象可能包含instructor
属性,该属性是课程的0..n教师对象的数组。对于instructor
数组的每个成员,我需要调用另一个API来获取其他数据。当该调用返回时,我需要将其插入到正确的教师对象中。
最后,当一切都完成后,数据将传递给模板以供快递渲染并返回给客户端。
我尝试使用async
使用async.waterfall
,并且在进行概念验证时仅使用其中一个教师配置文件(例如,不循环使用{{1}}时取得了一些成功数组,只是得到教师[0])。异步模块的文档很全面,但相当密集,我很难确定我实际需要做什么。我有一个弗兰肯斯坦组合的各种嵌套异步调用仍然没有工作。
我并不十分关心如何完成任务 - 流量控制,承诺,魔法小精灵尘埃等等。任何提示都非常赞赏。
答案 0 :(得分:3)
将Q用于承诺,您可以做以下事情:
return Q
.all(course_ids.map(function(course) {
return HTTP.GET(course); // Assuming this returns a promise
}))
.then(function(course_data) {
var instructors = [];
course_data.forEach(function(course) {
var p = Q
.all(course.instructor.map(function(instructor) {
return HTTP.GET(instructor.id);
}))
.then(function(instructors) {
course.instructors_data = instructors;
return course;
});
promises.push(p);
});
return Q.all(promises);
});
将使用包含课程的数组解析,每个课程都包含
其instructors_data
值中的一组教师数据。
答案 1 :(得分:1)
您可以使用async.each()
,它会并行执行API请求(假设服务器端没有并发API请求限制,如果是这种情况,请改用async.eachLimit()
):< / p>
async.each(instructors, function(instructor, callback) {
// call API here, store result on `instructor`,
// and call `callback` when done
}, function(err){
if (err)
console.log('An error occurred while processing instructors');
else
console.log('All instructors have been processed successfully');
});