2017-11-10 25 views
0

具體來說,給定一個數據列表,我希望遍歷該列表併爲之前的所有數據元素執行一次提取操作。正如所寫的那樣,代碼立即在整個列表中迭代,同時啓動所有操作。然後,即使提取操作仍在運行,那麼在數據可能已經被處理之前,我仍然會運行該調用。如何在Promises循環之後運行回調?

我讀了一些關於將所有Promises放在一個數組中,然後將該數組傳遞給Promise.all()調用,隨後是一個能夠按預期方式訪問所有已處理數據的函數,但我不是確定在這種情況下究竟該怎麼做,因爲我在這個for循環中嵌套了Promises

 for(var i in repoData) { 
      var repoName = repoData[i].name; 
      var repoUrl = repoData[i].url; 
      (function(name, url) { 
       Promise.all([fetch(`https://api.github.com/repos/${username}/${repoData[i].name}/commits`), 
        fetch(`https://api.github.com/repos/${username}/${repoData[i].name}/pulls`)]) 
       .then(function(results) { 
        Promise.all([results[0].json(), results[1].json()]) 
        .then(function(json) { 
         //console.log(json[0]); 
         var commits = json[0]; 
         var pulls = json[1]; 
         var repo = {}; 
         repo.name = name; 
         repo.url = url; 
         repo.commitCount = commits.length; 
         repo.pullRequestCount = pulls.length; 
         console.log(repo); 
         user.repositories.push(repo); 
        }); 
       }); 
      })(repoName, repoUrl); 
     } 
    }).then(function() { 
     var payload = new Object(); 
     payload.user = user; 
     //console.log(payload); 
     //console.log(repoData[0]); 
     res.send(payload); 
    }); 
+0

這是不是你應該使用的承諾。 .. –

+0

問題代碼是否完整?什麼是最後的'.then()'鏈接? – guest271314

回答

4

一般來說,當你需要爲陣列中的全部項目的運轉異步操作,答案是使用Promise.all(arr.map(...))這種情況下,似乎也不例外。

還記得,你需要在你的then回調return值,以便就值傳遞給下一個then(或到Promise.all聚集一切)。

當面臨複雜的情況時,它有助於將其分解成更小的塊。在這種情況下,您可以將代碼隔離爲查詢單個回購數據到自己的函數中。一旦你這樣做,代碼來查詢數據他們的所有歸結爲:

Promise.all(repoData.map(function (repoItem) { 
    return getDataForRepo(username, repoItem); 
})) 

請嘗試以下方法:

// function to query details for a single repo 
function getDataForRepo(username, repoInfo) { 
    return Promise 
    .all([ 
     fetch(`https://api.github.com/repos/${username}/${repoInfo.name}/commits`), 
     fetch(`https://api.github.com/repos/${username}/${repoInfo.name}/pulls`) 
    ]) 
    .then(function (results) { 
     return Promise.all([results[0].json(), results[1].json()]) 
    }) 
    .then(function (json) { 
     var commits = json[0]; 
     var pulls = json[1]; 

     var repo = { 
     name: repoInfo.name, 
     url: repoInfo.url, 
     commitCount: commits.length, 
     pullRequestCount: pulls.length 
     }; 

     console.log(repo); 
     return repo; 
    }); 
} 

Promise.all(repoData.map(function (repoItem) { 
    return getDataForRepo(username, repoItem); 
})).then(function (retrievedRepoData) { 
    console.log(retrievedRepoData); 

    var payload = new Object(); 
    payload.user = user; 
    //console.log(payload); 
    //console.log(repoData[0]); 
    res.send(payload); 
});