1

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');
1
  • 1
    You're looking for Promise.all -> Promise.all(arrayOfPromise).then(function (result) {}) Commented Sep 29, 2015 at 15:30

3 Answers 3

4

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');
    });
Sign up to request clarification or add additional context in comments.

Comments

2

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!"))

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.