2016-09-13 11 views
1

私はnode.jsの方が新しいので、非同期API呼び出しの約束が必要なプログラムを作成しています。私は私の研究で遭遇したいくつかのサンプルコードの実行に関する質問があります。Promise.all()とそれが解決されたときの理解

下記のコードは、APIをヒットして応答を待ち、その応答を約束として解決します。これは反復して行われ、すべての作成された約束は一連の約束に渡されます。最終的にPromiseの配列で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(); 

はPromise.allは()約束の中に押し込まれるAPI応答のALLを待つです。 getMovie(title)は、promises配列にプッシュされる前にすべての約束を解決するので、プッシュされた最初に解決された約束がPromise.all()セクションを実行する(配列は解決されます)?

+0

'Promise.all(約束)'行が何回呼び出されますか?それが起こったときに、パラメータ配列にいくつの項目がありますか?これらの質問に答えて、あなたは啓発されるでしょう。 ) – raina77ow

+2

私はあなたが約束していることを誤解していると思います。約束オブジェクトは直ちに作成され、クロージャーは元のオブジェクトに戻されます。連鎖の呼び出しは同期的に行われますが、解決策は順番に評価されます。 all内 - コレクションに追加された各約束は、解決時のコレクションの状態を評価します。それらのすべてが解決された状態に状態シフトを解決し、配列の内容 - その最初の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を呼び出すのと同等です。すべての約束が解決されるか、または1つが拒否されると、あなたのハンドラが呼び出されます。

3

promises配列にプッシュされる前に、「getMovie(title)がすべての約束を解決するので、混乱が起こると思います。

これは起こっていません。 return文に注目してください。 getMovie関数はすぐにPromiseオブジェクトを返し、後で(通常は)解決(または拒否)関数が呼び出されたときに解決されます。この場合は、非同期呼び出しの後です。

したがって、最初に約束が返され、後で約束が解決(または却下)されます。 Promise.allは、これらの約束が解決するまで待つ。

関連する問題