2016-09-13 1 views
1

저는 node.js보다 최신 버전이며 비동기 API 호출에 대한 약속이 필요한 프로그램을 작성했습니다. 내 연구에서 우연히 만난 예제 코드의 실행에 관한 질문이 있습니다.Promise.all() 및 해결 시점 이해

아래의 코드는 API를 강타하여 응답을 기다린 다음 그 응답을 약속으로 해결합니다. 이것은 반복적으로 행해지 며 모든 생성 된 약속은 일련의 약속으로 전달됩니다. 결국 Promise.all()이 약속 배열에서 호출되고 .then()가 더 많은 코드가 배열을 반복하고 페이지에 이미지를 추가하기 위해 실행됩니다.

function getMovie(title) { 
    return new Promise(function(resolve, reject) { 
    var request = new XMLHttpRequest(); 

    request.open('GET', 'http://mymovieapi.com/?q=' + title); 
    request.onload = function() { 
    if (request.status == 200) { 
    resolve(request.response); // we get the data here, so resolve the Promise 
    } else { 
     reject(Error(request.statusText)); // if status is not 200 OK, reject. 
    } 
    }; 

    request.onerror = function() { 
     reject(Error("Error fetching data.")); // error occurred, so reject the Promise 
    }; 

    request.send(); // send the request 
}); 
} 

function fetchMovies() { 
    var titles = document.getElementById('titles').value.split(','); 
    var promises = []; 

    for (var i in titles) { 
    promises.push(getMovie(titles[i])); // push the Promises to our array 
    } 

    Promise.all(promises).then(function(dataArr) { 
    dataArr.forEach(function(data) { 
    var img = JSON.parse(data)[0].poster.imdb; 

    document.getElementById('movies').innerHTML =  document.getElementById('movies').innerHTML + '<img src="' + img + '"/>'; 
    }); 
    }).catch(function(err) { 
    console.log(err); 
    }); 
}; 
fetchMovies(); 

은 내가 여기에 이해 아니에요하면 API의 모든 응답이 약속에 푸시하는 Promise.all()가 대기하는 것입니다. getMovie (title)는 약속 배열에 푸시되기 전에 모든 약속을 해결하기 때문에 푸시 된 첫 번째 해결 약속이 Promise.all() 섹션을 실행하게하지 않아야합니다 (1 개의 약속 중 1 개). 배열이 해결됨)?

+0

'Promise.all (promises)'행이 몇 번 호출 되었습니까? 그것이 발생했을 때 매개 변수 배열에 얼마나 많은 항목이 있습니까? 이 질문에 대답하면 깨달음을 얻을 수 있습니다.) – raina77ow

+2

나는 당신이 어떤 약속을하고 있는지 오해한다고 생각합니다. promise 객체가 즉시 생성되고 closure는 thenable을 통해 다시 전달됩니다. 연쇄 호출은 동기식으로 발생하지만 결의문은 차례로 평가합니다. 모두 - 컬렉션에 추가 된 각 약속은 해결시 컬렉션 상태를 평가합니다. 모두가 해결 된 상태로 상태 전환을 해결하고 배열 내용 (첫 번째 getMedia 함수의 결과)이 전달됩니다. –

+0

안녕 스콧, 몽구스를 이해하면 아마도이 링크가 도움이 될 것입니다 http : //stackoverflow.com/questions/39470090/node-js-detect-when-two-mongoose-find-are-finished/39471376#39471376 – vdj4y

답변

0

Promise.all으로 전화 할 때까지 배열은 Promise 개체로 채워져 있습니다. Promise.all은 모든 약속에 .then을 호출하는 것과 같습니다. 모든 약속이 해결되거나 하나가 거부되면 처리기가 호출됩니다.

3

나는 promises 배열에 푸시되기 전에 getMovie(title)가 모든 약속을 해결하기 때문에 혼란이 올 것이라고 생각합니다.

이것은 발생하지 않습니다. return 문을 주목하십시오. getMovie 함수는 즉시 Promise 개체를 반환하고 나중에 (일반적으로) 비동기 호출 후 resolve (또는 reject) 함수가 호출 될 때 해결됩니다.

그래서 처음에는 약속을 반환하고 나중에 약속이 해결됩니다 (또는 거부). Promise.all은 이러한 약속이 해결 될 때까지 기다립니다.