[英]How can I make jquery wait for one function to finish before executing another function?
[英]How can I use a javascript promise to make one function wait for another to finish running asynchronously?
// 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 之前,它仍然不会等待 populateVenueIDs。
我还尝试了 await、promise 和 then 的变体。 我已经阅读了大约 15 个关于这些主题的教程,但没有一个足够接近我想要的。 我不想使用超时(90% 的教程都使用),因为这会不必要地减慢应用程序的速度。 我必须使用 async 来满足分配要求。 请帮助我将这些点联系起来以应用在这种情况下适用的承诺和/或等待/然后。
您的populateVenueIDs
函数只是解析为 done 而不等待onload
函数。 如果可以, fetch
将是一个不错的选择,因为它返回承诺,但 IE 不支持。
您可以做的是为循环的每次迭代创建一个承诺,并使用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);
}
虽然我强烈认为@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 添加他的 fetch 解决方案之前发布了这个:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.