使用带有可通过Promise.all读取的JavaScript / ES6的for循环创建获取承诺数组。 [英] Create an array of fetch promises using a for loop with JavaScript/ES6 that can be read via Promise.all?

查看:81
本文介绍了使用带有可通过Promise.all读取的JavaScript / ES6的for循环创建获取承诺数组。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,在不打扰任何底层用户的情况下,我需要从许多API中访问数据才能运行脚本。在执行脚本之前,通常需要舒服地完成所有数据的加载:我只声明一些获取请求,编写Promise.all,然后继续执行该函数。

So, without boring anyone with the backstory, I need to access data from a number of APIs in order to run my script. The data needs to all be loaded before I execute the script, which I'm normally comfortable doing: I just declare some fetch requests, write a Promise.all, then continue on with the function.

但是,我使用某种API遇到了麻烦,它限制了我可以将一个请求中的结果数限制为100,并且我需要查询所有结果。我认为这没什么大不了的,因为我认为可以通过在请求末尾附加& page = X来提出几个额外的请求。

HOWEVER, I've hit something of a snafu with a certain API that limits the number of results I can pull from one request to 100 and I need to query all of the results. I didn't think this was a huge deal since I figured I can just make a couple extra requests by affixing "&page=X" to the end of the request.

然后,计划是从API请求页面总数,然后将其馈入for循环,以将许多获取请求推送到一个promise数组中(例如,link:// to / api / data& ; page = 1,link:// to / api / data& page = 2等)。但是,当我实际尝试使用for循环创建此数组时,该数组返回空。这是我的工作:

The plan, then, is to request the total number of pages from the API and then feed that into a for loop to push a number of fetch requests into an array of promises (i.e., link://to/api/data&page=1, link://to/api/data&page=2, etc). When I actually attempt to create this array with a for loop, though, the array returns empty. Here's my work:

const dataUrlNoPage = 'link/to/api/data&page=';
const totalPages = 3; //usually pulled via a function, but just using a static # for now

let apiRequestLoop = function(inp) {
  return new Promise(function(resolve){
    let promiseArray = [];
    for (let i = 1; i <= inp; i++) {
      let dataUrlLoop = dataUrlNoPage + i;
      fetch(dataUrlLoop).then(function(response){
        promiseArray.push(response.json());
      })
     }
    resolve(promiseArray);
  })
}

let finalPromiseArray = apiRequestLoop(totalPages).then(result => {
  let requestArray = [apiRequest1,apiRequest2];
  //requestArray contains earlier fetch promises
  result.forEach(foo => {
    requestArray.push(foo);
    }
  );
  return requestArray;
});

所以,令我绊倒的是真正的循环,以及它如何不返回承诺。当我在控制台中查看它时,它显示为空白数组,但是我可以对其进行扩展并看到我期望的承诺。我看到下面的值刚刚被评估响应。但是,无论写多少个Promise或.thens,该数组都不会在运行时实际填充。

So, what's tripping me up is really the loop, and how it's not returning an array of promises. When I look at it in the console, it shows up as a blank array, but I can expand it and see the promises I was expecting. I see the "Value below was evaluated just now" response. No matter how many promises or .thens, I write, however, the array is never actually populated at run time.

这是怎么回事?

(此外,只是为了减少这一问题,是的,我正在尝试访问的API是Wordpress。环顾四周,大多数人建议创建一个自定义终结点,但是让我们假设出于这个项目的目的,我禁止这样做。)

(Also, just to cut this line of questioning off a bit, yes, the API I'm trying to access is Wordpress. Looking around, most people suggest creating a custom endpoint, but let's assume for the purpose of this project I am forbidden from doing that.)

推荐答案

您在这里遇到几个问题。

You have several problems here.

第一个问题是您具有新承诺本身包含承诺创建。不要这样!这是一个确定的反模式,不会使您的代码保持整洁。

The first is that you have the function provided to new Promise itself containing promise creations. Don't do this! It's a definite anti-pattern and doesn't keep your code clean.

第二个是这段基本代码:

The second is this basic bit of code:

let promiseArray = [];
for (let i = 1; i <= inp; i++) {
  let dataUrlLoop = dataUrlNoPage + i;
  fetch(dataUrlLoop).then(function(response){
    promiseArray.push(response.json());
  })
 }
resolve(promiseArray);

这是说:


  1. 创建一个空数组

  2. 通过另一个数组循环,执行HTTP请求

  3. 用空数组解决您的诺言

  4. HTTP请求完成后,将它们添加到数组

  1. create an empty array
  2. loop through another array, doing HTTP requests
  3. resolve your promise with the empty array
  4. when the HTTP requests are completed, add them to the array

第四步总是在第三步之后进行。

Step four will always come after step three.

因此,您需要随行添加 promises 到数组中,并在全部完成后解决总体承诺。

So, you need to add the promises to your array as you go along, and have the overall promise resolve when they are all complete.

let apiRequestLoop = function(inp) {
  let promiseArray = [];
  for (let i = 1; i <= inp; i++) {
    let dataUrlLoop = dataUrlNoPage + i;
    promiseArray.push(fetch(dataUrlLoop).then(function(response) {
      return response.json();
    }));
  }
  return Promise.all(promiseArray);
}

或者,带有箭头功能可以清理东西:

or, with an arrow function to clean things up:

let apiRequestLoop = function(inp) {
  let promiseArray = [];
  for (let i = 1; i <= inp; i++) {
    let dataUrlLoop = dataUrlNoPage + i;
    promiseArray.push(fetch(dataUrlLoop).then(response => response.json()));
  }
  return Promise.all(promiseArray);
}

这篇关于使用带有可通过Promise.all读取的JavaScript / ES6的for循环创建获取承诺数组。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆