Joe*_*per 1 javascript arrays es6-promise fetch-api
因此,为了不让任何人对背景故事感到厌烦,我需要从许多 API 访问数据才能运行我的脚本。在执行脚本之前需要加载所有数据,我通常很乐意这样做:我只需声明一些获取请求,编写 Promise.all,然后继续执行该函数。
然而,我遇到了某个 API 的问题,该 API 将我可以从一个请求提取的结果数量限制为 100 个,并且我需要查询所有结果。我认为这没什么大不了的,因为我想我可以通过在请求末尾附加“&page=X”来提出几个额外的请求。
那么,计划是从 API 请求页面总数,然后将其输入到 for 循环中,以将多个获取请求推送到 Promise 数组中(即 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;
});
Run Code Online (Sandbox Code Playgroud)
所以,真正让我困惑的是循环,以及它如何不返回一系列承诺。当我在控制台中查看它时,它显示为空白数组,但我可以扩展它并查看我期望的承诺。我看到“下面的值刚刚被评估”响应。然而,无论我写了多少个 Promise 或 .thens,该数组在运行时都不会实际填充。
这是怎么回事?我不能通过 for 循环生成 fetch 承诺吗?
(另外,为了稍微打断这一行疑问,是的,我尝试访问的 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);
Run Code Online (Sandbox Code Playgroud)
这说:
第四步总是在第三步之后发生。
因此,您需要在进行过程中将承诺添加到数组中,并在全部完成后解决整体承诺。
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);
}
Run Code Online (Sandbox Code Playgroud)
或者,使用箭头函数来清理内容:
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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8396 次 |
| 最近记录: |