I think that I'm looking for promise but I don't see how to use it in my case.
I would like to console.log('ended')
only when all my async code is done.
I have a callback for the DZ.api but not for forEach()
, what is the best way for doing that ?
_.forEach(filteredTracks, function(n) {
DZ.api('/playlist/'+ n.id +'/tracks', function(response) {
_.forEach(response.data, function(n) {
SP.api('/search/'+n.title, function(response) {
console.log(response);
});
});
});
});
console.log('ended');
You're looking for Promise.all -> Promise.all(arrayOfPromise).then(function (result) {})
With your current code, if SP.api is already Promise compatible, just do :
_.map(filteredTracks, function(n) {
return DZ.api('/playlist/'+ n.id +'/tracks')
.then(function (response) {
_.map(response.data, function(n) {
return SP.api('/search/'+n.title);
});
return Promises.all(response.data);
});
});
});
Promise.all(filteredTracks)
.then(function (results) {
console.log('ended');
});
If SP.api and DZ Api does not return a Promise you can :
Promisify SP.api DZ Api and and use the same code I wrote before
Or return promises in the ._map
_.map(filteredTracks, function(n) {
var promise = new Promise(function (resolve, reject) {
DZ.api('/playlist/'+ n.id +'/tracks', function (response) {
_.map(response.data, function(n) {
var insidePromise = new Promise(function (resolve, reject) {
return SP.api('/search/'+n.title, function (result) {
resolve(result);
});
})
return insidePromise;
});
resolve(Promises.all(response.data));
});
});
});
return promise;
});
Promise.all(filteredTracks).then(function (results) {
console.log('ended');
});
What you want is to replace forEach
with map
and have each call return a Promise, concatenating the results of the inner loop since you have two levels. Then you pass the array of Promises to Promise.all()
, which creates a Promise that resolves when all the Promises in the array have resolved. To do that, you'll have to refactor your code to return a Promises from that DZ.api
function instead of using a callback. In short:
let promises = filteredTracks.map(track => {
return DZ.promisedApi(track).then(response => {
return Promise.all(response.data.map(n => SP.promisedApi(n))
})
})
Promise.all(promises).then(() => console.log("done!"))
You did not specify what libraries you are using but overall I can recommend you to save the promises of all API calls into an array and then using Promises.all()
So you would have something like (WARNING: untested code, just for reference):
var promisesArray = []
_.forEach(filteredTracks, function(n) {
DZ.api('/playlist/'+ n.id +'/tracks', function(response) {
_.forEach(response.data, function(n) {
promisesArray.push( SP.api('/search/'+n.title, function(response) {
console.log(response);
}));
});
});
});
Promise.all(promisesArray)
.then(function(value){
console.log('ended');
})
Basically, as stated on the Promise reference page , Promise.all creates a new Promise that resolves when all promises passed as a parameter are resolved. Which in my opinion matches your use case.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.