For循环中的异步提取 - 访问结果(已完成)变量

问题描述 投票:0回答:2

我是JS异步的新手,我有一个问题:如果所有查询都完成,如何开始处理已创建的数组。我在for循环中获取页面。那是我的代码:

var allOrgReposData = [];
var repoContributorsUrls = [];
for (var i=1; i <= orgPageIterations; i++) {
  var orgReposUrl = 'https://api.github.com/orgs/angular/repos?page='+i;
  fetch(orgReposUrl)
  .then(response => response.json())
  .then(orgReposData => {
    allOrgReposData = allOrgReposData.concat(orgReposData);
    console.log(allOrgReposData);
   })
}  

正如您可以看到allOrgReposData数组是在for循环上创建的,但如果我尝试在此数组上执行某些操作,脚本会在每次迭代时执行此操作,因此我的操作会被多次执行,而不是执行一次exapmle(页面上30项):30; 60; 90; 120; 150; 171 = 621而不是171。

是否可以“等待”完成提取并在没有这个的情况下访问数组。 “乘法”?

问候!

javascript json asynchronous
2个回答
0
投票

您可以使用Promise.all,它将等到所有承诺完成:

var allOrgReposData = [];
var repoContributorsUrls = [];

var promises = [];
let orgPageIterations = 1;

for (var i = 1; i <= orgPageIterations; i++) {
  let orgReposUrl = 'https://api.github.com/orgs/angular/repos?page=' + i;
  promises.push(fetch(orgReposUrl).then(response => response.json()));
}

Promise.all(promises)
  .then(data => {
    allOrgReposData = data;
    console.log(allOrgReposData);
  })
  .catch(err => console.error(err));

请注意,我也将var orgReposUrl更改为let orgReposUrl以使我们成为区块范围。


0
投票

您可以跟踪使用变量进行的调用次数:

var allOrgReposData = [];
var repoContributorsUrls = [];
var callSuccess = 1; //Variable keeping track of your ajax calls
for (var i=1; i <= orgPageIterations; i++) {
  var orgReposUrl = 'https://api.github.com/orgs/angular/repos?page='+i;
  fetch(orgReposUrl)
  .then(response => response.json())
  .then(orgReposData => {
    allOrgReposData = allOrgReposData.concat(orgReposData);
    console.log(allOrgReposData);
    callSuccess++; //Increment your var for each call

    if(callSuccess == orgPageIterations){ //If every call has already been made, then continue
      //DO YOUR THING HERE
    }
   })
}  
© www.soinside.com 2019 - 2024. All rights reserved.