简体   繁体   中英

How do I asynchronously query an API on an array of objects and then mutate each object correctly? (Using promises correctly)

I have an array of movies with IDs, but without ratings. I want to query a movie database to get the ratings for each movie, so I iterate over each object using fetch(url) to query the API and then use .then(function(response) { add_rating_to_specific_movie}) .

The problem is, .then is an async response, and I have no way of knowing which movie has returned a rating value so that I can mutate the correct movie object with the rating. And I can't create a new array with the returned values, because some movies will return status: movies not found , and I have no way of knowing which movies are unrated.

Could use some guidance on a good algorithm for using promises here. Thanks!

You don't show your actual code for how you are iterating the array of movies so we can only provide a conceptual answer (next time show your actual iteration code please). But, in concept, you just use a function to pass the index or object separately for each array element and then you can access that index or object in the .then() handler. In this case, if you use .forEach() to iterate your array, the object from your array of objects that you are iterating and the index of that object are both passed to you in a function that will be uniquely available for each separate request.

For example, here's one concept that would work:

var movies = [....];   // array of movie objects
movies.forEach(function(movie, index) {
     // construct url for this movie
     fetch(movieURL).then(function(data) {
        // use the data to set the rating on movie
        movie.rating = ...
     });
});

If you want to use promises to know when all the requests are done, you can do this using Promise.all() :

var movies = [....];   // array of movie objects
Promise.all(movies.map(function(movie, index) {
     // construct url for this movie
     return fetch(movieURL).then(function(data) {
        // use the data to set the rating on movie
        movie.rating = ...
     });
})).then(function() {
    // all ratings updated now
});

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM