nodejs async:多个依赖的HTTP API调用

时间:2014-04-17 18:46:35

标签: node.js asynchronous async.js

我正在处理一个项目,该项目涉及向不同的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])。异步模块的文档很全面,但相当密集,我很难确定我实际需要做什么。我有一个弗兰肯斯坦组合的各种嵌套异步调用仍然没有工作。

我并不十分关心如何完成任务 - 流量控制,承诺,魔法小精灵尘埃等等。任何提示都非常赞赏。

2 个答案:

答案 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');
});