Fetch 不存储数组 for 循环后的值 - Javascript
Fetch doesn't store the values after the array for loop - Javascript
我想为从维基媒体 API 获取的位置数组中的每个对象添加描述 属性 但是当我在循环中记录它的值时,它就在那里,但在循环之外, 它被删除了。
我用 async/await 函数或 Promise.all() 寻找解决方案,但没有成功。
有没有办法正确存储该值以便以后访问它??
let locations = [
{
latLng: [33.975561111111,28.555830555556],
name: 'Saint Catherine\'s Monastery',
searchTerm: 'Saint Catherine\'s Monastery',
urlSerchTerm: 'Saint%20Catherine\'s%20Monastery'
},
{
latLng: [29.91667,31.2],
name: 'Bibliotheca Alexandrina',
searchTerm: 'Bibliotheca Alexandrina',
urlSerchTerm: 'Bibliotheca%20Alexandrina'
}
];
async function fetchAsync (site, location) {
// await response of fetch call
let response = await fetch(site);
// only proceed once promise is resolved
let data = await response.json();
// only proceed once second promise is resolved
location.description = data[2][0];
return location.description;
}
// let fetches = [];
for (let i = 0; i < locations.length; i++) {
let site = `https://en.wikipedia.org/w/api.php?action=opensearch&search=${locations[i].urlSerchTerm}&limit=1&namespace=0&format=json&origin=*`;
fetchAsync(site, locations[i])
}
console.log(locations[1].description)
这是我的 Promise.all
解决方案:
我正在通过 .map
ping locations
数组来创建 Promise 数组。
let locations = [
{
latLng: [33.975561111111, 28.555830555556],
name: "Saint Catherine's Monastery",
searchTerm: "Saint Catherine's Monastery",
urlSerchTerm: "Saint%20Catherine's%20Monastery"
},
{
latLng: [29.91667, 31.2],
name: "Bibliotheca Alexandrina",
searchTerm: "Bibliotheca Alexandrina",
urlSerchTerm: "Bibliotheca%20Alexandrina"
}
];
Promise.all(
locations.map( location => new Promise(async (resolve, reject) => {
let site = `https://en.wikipedia.org/w/api.php?action=opensearch&search=${location.urlSerchTerm}&limit=1&namespace=0&format=json&origin=*`,
response = await fetch(site),
data = await response.json();
location.description = data[2][0];
// console.log("Got description = ", location.description)
resolve();
})))
.then(() => {
console.log("locations[1].description = ", locations[1].description);
});
这只是一个时间问题。您的 fetch
调用正在 异步执行 而代码片段最后一行中的 console.log(...)
语句正在 同步执行 .换句话说,对 fetch
发出的请求的响应将在 console.log(...)
之后 return,并且 description
属性仍未定义。
您可以通过查看下面的代码让自己相信这一点,其中 console.log(...)
语句包含在超时中。现在将记录获取的描述而不是 undefined
.
let locations = [
{
latLng: [33.975561111111,28.555830555556],
name: 'Saint Catherine\'s Monastery',
searchTerm: 'Saint Catherine\'s Monastery',
urlSerchTerm: 'Saint%20Catherine\'s%20Monastery'
},
{
latLng: [29.91667,31.2],
name: 'Bibliotheca Alexandrina',
searchTerm: 'Bibliotheca Alexandrina',
urlSerchTerm: 'Bibliotheca%20Alexandrina'
}
];
async function fetchAsync (site, location) {
// await response of fetch call
let response = await fetch(site);
// only proceed once promise is resolved
let data = await response.json();
// only proceed once second promise is resolved
location.description = data[2][0];
return location.description;
}
// let fetches = [];
for (let i = 0; i < locations.length; i++) {
let site = `https://en.wikipedia.org/w/api.php?action=opensearch&search=${locations[i].urlSerchTerm}&limit=1&namespace=0&format=json&origin=*`;
fetchAsync(site, locations[i])
}
window.setTimeout(() => {console.log(locations);}, 5000);
您可以按照@JeremyThille 的建议使用Promise.all
解决此问题。 解释了 Promise.all
的第二次使用,以防混淆。
let locations = [
{
latLng: [33.975561111111,28.555830555556],
name: 'Saint Catherine\'s Monastery',
searchTerm: 'Saint Catherine\'s Monastery',
urlSerchTerm: 'Saint%20Catherine\'s%20Monastery'
},
{
latLng: [29.91667,31.2],
name: 'Bibliotheca Alexandrina',
searchTerm: 'Bibliotheca Alexandrina',
urlSerchTerm: 'Bibliotheca%20Alexandrina'
}
];
const fetchDescription = (location) => fetch(`https://en.wikipedia.org/w/api.php?action=opensearch&search=${location.urlSerchTerm}&limit=1&namespace=0&format=json&origin=*`);
const descriptionRequests = locations.map(fetchDescription);
Promise.all(descriptionRequests)
.then(responses => Promise.all(responses.map(r => r.json())))
.then(descriptions => {
descriptions.forEach((description, index) => { locations[index].description = description[2][0]; });
})
.then(() => {
console.log(locations);
});
我想为从维基媒体 API 获取的位置数组中的每个对象添加描述 属性 但是当我在循环中记录它的值时,它就在那里,但在循环之外, 它被删除了。
我用 async/await 函数或 Promise.all() 寻找解决方案,但没有成功。
有没有办法正确存储该值以便以后访问它??
let locations = [
{
latLng: [33.975561111111,28.555830555556],
name: 'Saint Catherine\'s Monastery',
searchTerm: 'Saint Catherine\'s Monastery',
urlSerchTerm: 'Saint%20Catherine\'s%20Monastery'
},
{
latLng: [29.91667,31.2],
name: 'Bibliotheca Alexandrina',
searchTerm: 'Bibliotheca Alexandrina',
urlSerchTerm: 'Bibliotheca%20Alexandrina'
}
];
async function fetchAsync (site, location) {
// await response of fetch call
let response = await fetch(site);
// only proceed once promise is resolved
let data = await response.json();
// only proceed once second promise is resolved
location.description = data[2][0];
return location.description;
}
// let fetches = [];
for (let i = 0; i < locations.length; i++) {
let site = `https://en.wikipedia.org/w/api.php?action=opensearch&search=${locations[i].urlSerchTerm}&limit=1&namespace=0&format=json&origin=*`;
fetchAsync(site, locations[i])
}
console.log(locations[1].description)
这是我的 Promise.all
解决方案:
我正在通过 .map
ping locations
数组来创建 Promise 数组。
let locations = [
{
latLng: [33.975561111111, 28.555830555556],
name: "Saint Catherine's Monastery",
searchTerm: "Saint Catherine's Monastery",
urlSerchTerm: "Saint%20Catherine's%20Monastery"
},
{
latLng: [29.91667, 31.2],
name: "Bibliotheca Alexandrina",
searchTerm: "Bibliotheca Alexandrina",
urlSerchTerm: "Bibliotheca%20Alexandrina"
}
];
Promise.all(
locations.map( location => new Promise(async (resolve, reject) => {
let site = `https://en.wikipedia.org/w/api.php?action=opensearch&search=${location.urlSerchTerm}&limit=1&namespace=0&format=json&origin=*`,
response = await fetch(site),
data = await response.json();
location.description = data[2][0];
// console.log("Got description = ", location.description)
resolve();
})))
.then(() => {
console.log("locations[1].description = ", locations[1].description);
});
这只是一个时间问题。您的 fetch
调用正在 异步执行 而代码片段最后一行中的 console.log(...)
语句正在 同步执行 .换句话说,对 fetch
发出的请求的响应将在 console.log(...)
之后 return,并且 description
属性仍未定义。
您可以通过查看下面的代码让自己相信这一点,其中 console.log(...)
语句包含在超时中。现在将记录获取的描述而不是 undefined
.
let locations = [
{
latLng: [33.975561111111,28.555830555556],
name: 'Saint Catherine\'s Monastery',
searchTerm: 'Saint Catherine\'s Monastery',
urlSerchTerm: 'Saint%20Catherine\'s%20Monastery'
},
{
latLng: [29.91667,31.2],
name: 'Bibliotheca Alexandrina',
searchTerm: 'Bibliotheca Alexandrina',
urlSerchTerm: 'Bibliotheca%20Alexandrina'
}
];
async function fetchAsync (site, location) {
// await response of fetch call
let response = await fetch(site);
// only proceed once promise is resolved
let data = await response.json();
// only proceed once second promise is resolved
location.description = data[2][0];
return location.description;
}
// let fetches = [];
for (let i = 0; i < locations.length; i++) {
let site = `https://en.wikipedia.org/w/api.php?action=opensearch&search=${locations[i].urlSerchTerm}&limit=1&namespace=0&format=json&origin=*`;
fetchAsync(site, locations[i])
}
window.setTimeout(() => {console.log(locations);}, 5000);
您可以按照@JeremyThille 的建议使用Promise.all
解决此问题。 Promise.all
的第二次使用,以防混淆。
let locations = [
{
latLng: [33.975561111111,28.555830555556],
name: 'Saint Catherine\'s Monastery',
searchTerm: 'Saint Catherine\'s Monastery',
urlSerchTerm: 'Saint%20Catherine\'s%20Monastery'
},
{
latLng: [29.91667,31.2],
name: 'Bibliotheca Alexandrina',
searchTerm: 'Bibliotheca Alexandrina',
urlSerchTerm: 'Bibliotheca%20Alexandrina'
}
];
const fetchDescription = (location) => fetch(`https://en.wikipedia.org/w/api.php?action=opensearch&search=${location.urlSerchTerm}&limit=1&namespace=0&format=json&origin=*`);
const descriptionRequests = locations.map(fetchDescription);
Promise.all(descriptionRequests)
.then(responses => Promise.all(responses.map(r => r.json())))
.then(descriptions => {
descriptions.forEach((description, index) => { locations[index].description = description[2][0]; });
})
.then(() => {
console.log(locations);
});