// TODO: FIX CODE - IT IS STILL NOT WAITING FOR populateVenueIDs
// BEFORE CALLING populateFsPhotoRequestURLs
// must use async, not sync to meet assignment requirements.
let populateVenueIDs = new Promise(function(resolve, reject) {
for (let y = 0; y < window.coffeeShopLocations().length; y++) {
let getVenueIDFromFS = new XMLHttpRequest();
getVenueIDFromFS.open('GET', window.fsURL[y]);
getVenueIDFromFS.onload = function() {
let responseFromFS = JSON.parse(getVenueIDFromFS.responseText);
window.fsVenueID[y] = responseFromFS.response.venues[0].id;
console.log(window.fsVenueID[y]);
};
getVenueIDFromFS.send();
}
resolve("done!");
});
function populateFsPhotoRequestURLs() {
for (let y = 0; y < window.coffeeShopLocations().length; y++) {
window.fsPhotoEndpoint[y] = 'https://api.foursquare.com/v2/venues/'
+ window.fsVenueID[y] + '/photos';
window.fsPhotoRequestURL[y] = fsPhotoEndpoint + '?' + fsPhotoParams;
console.log(window.fsPhotoRequestURL[y]);
}
}
populateVenueIDs.then(
populateFsPhotoRequestURLs()
);
在运行populateFsPotoRequestURLs之前,它仍然不等待populateVenueID。
我还尝试了await,promise等各种变体。我已经阅读了大约15个关于这些主题的教程,但是没有一个教程足够接近我想要的。我不想使用超时(90%的教程使用了超时),因为那样会不必要地减慢应用程序的速度。我必须使用异步来满足分配要求。 请帮助我点点滴滴答应和/或等待/然后在这种情况下适用。
答案 0 :(得分:3)
您的populateVenueIDs
函数只是解析为完成,而无需等待onload
函数被调用。如果可以的话,fetch
将是一个不错的选择,因为它返回承诺,但IE不支持。
您可以做的是为循环的每次迭代创建一个Promise,并使用Promise.all(arrayOfPromises)
等待所有请求。这样甚至可以并行执行所有XMLHttpRequest
!
示例代码:
let populateVenueIDs = new Promise(function(resolve, reject) {
let promises = [];
for (let y = 0; y < window.coffeeShopLocations().length; y++) {
promises.push(new Promise(function (resolve) {
let getVenueIDFromFS = new XMLHttpRequest();
getVenueIDFromFS.open('GET', window.fsURL[y]);
getVenueIDFromFS.onload = function() {
let responseFromFS = JSON.parse(getVenueIDFromFS.responseText);
window.fsVenueID[y] = responseFromFS.response.venues[0].id;
console.log(window.fsVenueID[y]);
resolve();
};
getVenueIDFromFS.send();
}));
}
return Promise.all(promises)
.then(function () {
resolve('Done!');
})
});
正如您所说的,这是一个任务,您可能可以将ES6与async
和await
一起使用,这将是一个不错的解决方案:
async function populateVenueIDs() {
let promises = [];
for (let y = 0; y < window.coffeeShopLocations().length; y++) {
promises.push(new Promise(async resolve => {
const response = await fetch(window.fsURL[y]);
const data = await response.json();
window.fsVenueID[y] = data.venues[0].id;
resolve();
}));
}
await Promise.all(promises);
}
答案 1 :(得分:1)
虽然我坚信@JensV的答案正确,但我在评论中这么说,我只是想跟进使用fetch时代码的样子(我只包含了有关JensV的答案)
var promises = [];
for (let y = 0; y < window.coffeeShopLocations().length; y++) {
promises.push(fetch(window.fsURL[y])
.then(response => response.json())
.then(data => {
window.fsVenueID[y] = data.response.venues[0].id;
}));
}
编辑:为了后代的缘故,我在詹斯(Jens)添加他的提取解决方案之前就发布了此内容:)