簡體   English   中英

使用帶有JavaScript / ES6的for循環創建一個fetch promises數組,可以通過Promise.all讀取?

[英]Create an array of fetch promises using a for loop with JavaScript/ES6 that can be read via Promise.all?

因此,如果沒有任何背景故事,我需要從許多API訪問數據才能運行我的腳本。 在執行腳本之前需要加載所有數據,我通常會這樣做:我只是聲明一些獲取請求,寫一個Promise.all,然后繼續使用該函數。

但是,我遇到了一些使用某種API的問題,這限制了我可以從一個請求提取到100的結果數量,我需要查詢所有結果。 我不認為這是一個很大的交易,因為我想我可以通過在請求結束時加上“&page = X”來做幾個額外的請求。

然后,計划是從API請求總頁數,然后將其提供給for循環,以將多個獲取請求推送到promises數組中(即link:// to / api / data&page = 1 ,link:// to / api / data&page = 2等)。 但是,當我實際嘗試使用for循環創建此數組時,該數組返回空。 這是我的工作:

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;
});

那么,絆倒我的真正是循環,以及它是如何不返回一系列承諾的。 當我在控制台中查看它時,它顯示為一個空白數組,但我可以擴展它並查看我期望的承諾。 我看到“下面的價值剛剛評估”回應。 然而,無論有多少承諾或.thens,我寫道,數組在運行時從未實際填充過。

這是怎么回事? 我可以通過for循環生成fetch promises嗎?

(另外,只是為了減少這一問題,是的,我試圖訪問的API是Wordpress。環顧四周,大多數人建議創建一個自定義端點,但讓我們假設為了這個項目的目的我被禁止這樣做。)

你有幾個問題。

第一個是你有new Promise本身提供的函數包含promise創建。 不要這樣做! 這是一種明確的反模式,並不能保持代碼清潔。

第二個是這個基本的代碼:

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請求后,將它們添加到陣列中

第四步將始終在第三步之后。

因此,您需要在進行時向您的陣列添加承諾 ,並在完成后解決整體承諾。

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);
}

或者,用箭頭功能清理:

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);
}

幾點:

  • 你想實際將promises自己放入數組中,而不是在鏈接到promise的.then()推送到數組。
  • 你可能想跳過在你的函數中創建一個新的Promise。 只需從循環中獲取所有promise的數組,然后在數組上返回Promise.all

像這樣:

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

在你的最后.then陳述,在finalPromiseArray,你的結果將是所有承諾的結果的數組。 像這樣[response1, response2, response3, ...]

有關更多詳細信息,請參閱Promise.all文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM