2014-04-17 5 views
1

여러 HTTP GET 요청을 서로 다른 API에 적용하는 프로젝트를 진행 중입니다. 각 인터페이스는 마지막 API의 정보가 필요합니다. 중첩 된 callaback-and-counter-hell을 피하려고 노력 중이며 async 모듈을 사용하여 작동하도록했습니다.nodejs async : 여러 종속 HTTP API 호출

이것은 내가해야 할 일입니다. 나는 1..n 코스 식별자 배열 (['2014/summer/iat/100/d100', '2014/spring/bisc/372/d100'])을 가지고 있습니다. 배열의 각 코스에 대해 HTTP GET을 통해 코스 개요를 가져와야합니다. 각 윤곽선 객체 0..N 배열 인 instructor 속성을 포함 할 수있다

{ 
    "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": "[email protected]", 
     "name": "Frank Smith", 
     "roleCode": "PI" 
    }, 
    { 
     "lastName": "Doe", 
     "commonName": "John", 
     "phone": "1 555 555-9876", 
     "email": "[email protected]", 
     "name": "John Doe", 
     "roleCode": "PI" 
    } 
    ] 
} 

(생략 비 관련 분야의 무리)

결과 개요는 다음과 같이 보인다 강사 객체. instructor 배열의 각 구성원에 대해 추가 데이터를 얻기 위해 다른 API를 호출해야합니다. 호출이 돌아 오면 오른쪽 강사 객체에 삽입해야합니다.

마지막으로 모든 작업이 완료되면 데이터가 표현 용 템플릿으로 전달되어 클라이언트로 렌더링 및 반환됩니다.

async을 사용하여이 작업을 시도했지만 async.waterfall과 함께 성공한 경우 강사 프로필 중 하나만 가져 오는 개념 증명을 수행 할 때 (예 : 강사 [0]을 얻는 동안 배열을 반복하지 않음) . 비동기 모듈의 문서는 포괄적이지만 꽤 밀도가 높습니다. 실제로 수행해야 할 작업을 결정하는 데 어려움을 겪고 있습니다. 여러 가지 중첩 된 비동기 호출의 Frankenstein 조합을 사용했지만 여전히 작동하지 않았습니다.

나는 흐름 제어, 약속, 마술 픽시 먼지 등 어떤 작업을 수행하는지 실제로 신경 쓰지 않습니다. 어떤 힌트도 크게 감사드립니다. 약속에 대한 Q를 사용

답변

3

, 당신은 아마 이런 식으로 뭔가를 할 수 있습니다

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 값 강사의 데이터 배열을 포함, 각각의 과정을 포함하는 배열로 해결됩니다.

+0

나 ' 이것에 대한 약속을하기로 결정했습니다. 나는 코스의 윤곽을 가져 와서 일하는 첫 번째 단계를 가졌습니다. 그건 바보 같았어요. 나는 다음과 같은 부분을 약속하는 법을 배우는 과정에서 각 강사의 프로필을 수집하여 올바른 장소에 채우는 데 어려움을 겪고 있습니다. 콜백 (callback)과 카운터 (counter)를 사용하여 긴 길이로 작업하게했습니다. https://gist.github.com/grahamb/11306874 – grahamb

1

당신은 (서버 측에 아무런 동시 API 요청 제한이없는 가정이 사건의 경우, 대신 async.eachLimit() 사용) 병렬 API 요청을 할 것이다, async.each()을 사용할 수

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