因此,jsonBaseList 包含一个承诺列表。
是的,因为res.json() 返回了一个承诺。但是,当您显示 console.log 时,jsonBaseList 将是 [],因为该代码在任何承诺解决之前运行。
对于jsonBaseList 的代码在承诺解决后运行的代码中包含值的最小更改是:
// ...
// ...
let urlList = [
"https://url.to/resource1.json",
"https://url.to/resource2.json"
];
let promiseList = [];
let jsonBaseList = [];
urlList.forEach (function (url, i) {
promiseList.push (
fetch(url) .then (function (res) {
return res.json();
})
.then (function (value) { // ***
jsonBaseList[i] = value; // *** This is what I added
}) // ***
);
});
Promise
.all(promiseList)
.then (function () {
console.log('All done.'); // *** Use `jsonBaseList` here
})
// Removed the `console.log` here that would have logged `[]`
但是它可以简单得多;以上所有内容都可以替换为:
let urlList = [
"https://url.to/resource1.json",
"https://url.to/resource2.json"
];
Promise.all(urlList.map(url => fetch(url).then(response => response.json())))
.then(jsonBaseList => {
// ...use `jsonBaseList` here...
})
.catch(error => {
// ...handle/report error here...
});
请注意,您在Promise.all 上的then 处理程序中使用了jsonBaseList。我不会在更广泛的范围内声明它,因为在调用该处理程序之前它不会被填充(这就是你最后的console.log 将始终记录[] 的原因)。如果您在更广泛的范围内声明它,您可能会在它可用之前尝试使用它(如问题代码中所示)。
但如果想在更广泛的范围内填写,并且您意识到要等到以后才能填写,请添加:
let jsonBaseList = []; // *** Not filled in until the promises settle!
然后改变
.then(jsonBaseList => {
// ...use `jsonBaseList` here...
})
到
.then(list => {
jsonBaseList = list;
})
(或使用const 和jsonBaseList.push(...list)。)
旁注:您可能想要处理 HTTP 请求失败的可能性(即使网络请求成功 - 这是我写的关于 here 的 fetch API 中的枪,它不会拒绝 HTTP失败,只是网络故障)。所以:
let urlList = [
"https://url.to/resource1.json",
"https://url.to/resource2.json"
];
Promise.all(
urlList.map(
url => fetch(url).then(response => {
if (response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
return response.json();
})
)
)
.then(jsonBaseList => {
// ...use `jsonBaseList` here...
})
.catch(error => {
// ...handle/report error here...
});