使用带有 JavaScript/ES6 的 for 循环创建一个获取承诺数组,可以通过 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 循环以将多个获取请求推送到承诺数组(即 link://to/api/data&page=1,link://to/api/data&page=2,等等)。但是,当我实际尝试使用 for 循环创建此数组时,数组 returns 为空。这是我的作品:
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;
});
所以,真正让我感到困惑的是循环,以及它如何不返回一系列承诺。当我在控制台中查看它时,它显示为一个空白数组,但我可以展开它并看到我期望的承诺。我看到 "Value below was evaluated just now" 响应。然而,无论有多少 promises 或 .thens,我写的是,数组从未在 运行 时间实际填充。
这是怎么回事?我不能通过 for 循环生成提取承诺吗?
(另外,为了稍微打断这一行问题,是的,我尝试访问的 API 是 Wordpress。环顾四周,大多数人建议创建一个自定义端点,但让我们假设为了这个项目的目的,我被禁止这样做。)
几点:
- 您实际上想将 promise 本身放入数组中,而不是推送到与 promise 链接的
.then()
中的数组。
- 您可能想跳过在函数中创建新的 Promise。只需从循环中获取所有承诺的数组,然后在数组上 return 一个
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 documentation。
你这里有几个问题。
首先,您拥有提供给 new Promise
的函数,它本身包含 promise 的创建。不要这样做!这是一个明确的 anti-pattern 并且不会使您的代码保持整洁。
第二个是这段基本代码:
let promiseArray = [];
for (let i = 1; i <= inp; i++) {
let dataUrlLoop = dataUrlNoPage + i;
fetch(dataUrlLoop).then(function(response){
promiseArray.push(response.json());
})
}
resolve(promiseArray);
这表示:
- 创建一个空数组
- 遍历另一个数组,执行 HTTP 请求
- 用空数组解决你的承诺
- 当 HTTP 请求完成后,将它们添加到数组中
第四步总是在第三步之后。
因此,您需要在进行过程中将 promises 添加到您的数组中,并在它们全部完成时解决整个 promise。
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);
}
因此,为了不让任何人对背景故事感到厌烦,我需要访问来自多个 API 的数据,以便 运行 我的脚本。在我执行脚本之前需要加载所有数据,我通常很乐意这样做:我只是声明一些获取请求,写一个 Promise.all,然后继续执行该函数。
但是,我遇到了一些问题 API,这将我可以从一个请求中提取的结果数量限制为 100 个,我需要查询所有结果。我不认为这有什么大不了的,因为我认为我可以通过在请求末尾附加“&page=X”来提出几个额外的请求。
然后,计划是从 API 请求总页数,然后将其送入 for 循环以将多个获取请求推送到承诺数组(即 link://to/api/data&page=1,link://to/api/data&page=2,等等)。但是,当我实际尝试使用 for 循环创建此数组时,数组 returns 为空。这是我的作品:
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;
});
所以,真正让我感到困惑的是循环,以及它如何不返回一系列承诺。当我在控制台中查看它时,它显示为一个空白数组,但我可以展开它并看到我期望的承诺。我看到 "Value below was evaluated just now" 响应。然而,无论有多少 promises 或 .thens,我写的是,数组从未在 运行 时间实际填充。
这是怎么回事?我不能通过 for 循环生成提取承诺吗?
(另外,为了稍微打断这一行问题,是的,我尝试访问的 API 是 Wordpress。环顾四周,大多数人建议创建一个自定义端点,但让我们假设为了这个项目的目的,我被禁止这样做。)
几点:
- 您实际上想将 promise 本身放入数组中,而不是推送到与 promise 链接的
.then()
中的数组。 - 您可能想跳过在函数中创建新的 Promise。只需从循环中获取所有承诺的数组,然后在数组上 return 一个
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 documentation。
你这里有几个问题。
首先,您拥有提供给 new Promise
的函数,它本身包含 promise 的创建。不要这样做!这是一个明确的 anti-pattern 并且不会使您的代码保持整洁。
第二个是这段基本代码:
let promiseArray = [];
for (let i = 1; i <= inp; i++) {
let dataUrlLoop = dataUrlNoPage + i;
fetch(dataUrlLoop).then(function(response){
promiseArray.push(response.json());
})
}
resolve(promiseArray);
这表示:
- 创建一个空数组
- 遍历另一个数组,执行 HTTP 请求
- 用空数组解决你的承诺
- 当 HTTP 请求完成后,将它们添加到数组中
第四步总是在第三步之后。
因此,您需要在进行过程中将 promises 添加到您的数组中,并在它们全部完成时解决整个 promise。
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);
}