[英]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()
);
It is still not waiting for populateVenueIDs before running populateFsPotoRequestURLs.在运行 populateFsPotoRequestURLs 之前,它仍然不会等待 populateVenueIDs。
I have also tried variants of await, promise, and then.我还尝试了 await、promise 和 then 的变体。 I have read about 15 tutorials about those topics, but none are close enough to do what I want.
我已经阅读了大约 15 个关于这些主题的教程,但没有一个足够接近我想要的。 I don't want to use a timeout (which 90% of tutorials use) because that would unnecessarily slow down the application.
我不想使用超时(90% 的教程都使用),因为这会不必要地减慢应用程序的速度。 I have to use async to meet the assignment requirements.
我必须使用 async 来满足分配要求。 Please help me connect the dots to apply a promise and/or await/then that will apply in this situation.
请帮助我将这些点联系起来以应用在这种情况下适用的承诺和/或等待/然后。
Your populateVenueIDs
function just resolves to done without waiting for the onload
functions to be called.您的
populateVenueIDs
函数只是解析为 done 而不等待onload
函数。 If you can, fetch
would be a nice alternative because it returns promises but that isn't supported in IE.如果可以,
fetch
将是一个不错的选择,因为它返回承诺,但 IE 不支持。
What you can do, is create a promise for each iteration of your loop and use Promise.all(arrayOfPromises)
to wait for all requests.您可以做的是为循环的每次迭代创建一个承诺,并使用
Promise.all(arrayOfPromises)
等待所有请求。 This will even execute all XMLHttpRequest
in parallel!这甚至会并行执行所有
XMLHttpRequest
!
Example code:示例代码:
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!');
})
});
As you've said this is an assignment, you probably can use ES6 with async
and await
so this would be a fancy solution:正如您所说,这是一项任务,您可能可以将 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);
}
While I feel strongly that @JensV had the right answer, and I said so in my comment, I just wanted to follow up on what your code might look like if you used fetch (I only included the relevant piece of JensV's answer.虽然我强烈认为@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;
}));
}
EDIT: For posterity's sake I posted this before Jens added his fetch solution :)编辑:为了后人的缘故,我在 Jens 添加他的 fetch 解决方案之前发布了这个:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.