简体   繁体   中英

How to make an ajax call for each element of an array of objects, using promises?

I have this code:

       // _arrOfUsers = array of objects, each object represents a user. 
       //For example, a single object may be something like {name:"mike", id:"123"}    

            var _successUsers = function (_arrOfUsers) {            
                    var promises = [];   //empty array of promises

                        _arrOfUsers.forEach(function (user) {
                            promises.push(function () {
                                return $.Deferred(function (dfd) {
                                     $.post("//sessionID",
                                                queryServ.getAllUserDomainCommentsFunc("//currentDomainID", user.iD, "//currentDomainID", "//currentURL"),
                                        'text', 'text/plain', this,
                                        function (dataX) {
                                            dfd.resolve(dataX);
                                        });
                                }).promise();
                            });
                    });

                    $.when(promises).then(function (results) {
                        console.log(results);
                    });

                };

Some elements to understand this code:

**** Ajax call settings

  • url: sessionURL
  • data: data to send to the server is an external call to the module queryServ.js and the function getAllUserDomainCommentsFunct that returns a JSON object. It needs these parameters to work: currentDomain, userID, currentDomain (again), currentURL
  • type: text
  • contentType: text/plain
  • context: this

**** A comment is a jsonObject smilar to {id: "998", textOfcomment:"I commented this", target: "//targetID"}.

What I want to do is to make an ajax call for each user of the array "_arrOfUsers" to extract all his comments on the server; after all the "extractions" I need to get all the results (that are all the comments from all users) and print them in the console. The order is important for my code, this is why I'm using Promises.

I found the structure of this algorithm on a JSfiddle here on StackOverflow, but it doesn't work for me because it returns an array of functions and I can't understand why, probably because I've never used Promises during my career.

Thank you in advance, if there's something not clear please feel free to tell me.

There's no need to create a deferred here since $.post() already returns a promise and $.when() keeps the results in order for you. Instead, you can do this:

$.when.apply($, _arrOfUsers.map(function(user) {
    return $.post("//sessionID", queryServ.getAllUserDomainCommentsFunc("//currentDomainID", user.iD, "//currentDomainID", "//currentURL"));
})).then(function() {
    // all results available in order here as arguments to this callback
    // arguments[0][0] is the first result
    // arguments[1][0] is the second result
    // arguments[2][0] is the third result and so on 
    for (var i = 0; i < arguments.length; i++) {
        // arguments[i][0] is next one  of your results
    }
});

Note: I didn't quite understand what you were trying to do with the arguments to $.post() (you seem to have made up some arguments the jQuery doc doesn't show) so I simplified it somewhat, but you may need to tweak those $.post() arguments to suit your purpose.


Personally, I despise $.when() and how it interacts with jQuery ajax promises (very confusing to use) so I would cast the ajax promise to an ES6 promise and use Promise.all() (using Bluebird for promise support if older browser support is needed).

Promise.all(_arrOfUsers.map(function(user) {
    return Promise.resolve($.post("//sessionID", queryServ.getAllUserDomainCommentsFunc("//currentDomainID", user.iD, "//currentDomainID", "//currentURL")));
})).then(function(results) {
    // results is an array of results in order
});

Or if you include Bluebird, you can use:

Promise.map(_arrOfUsers, function(user) {
    return Promise.resolve($.post("//sessionID", queryServ.getAllUserDomainCommentsFunc("//currentDomainID", user.iD, "//currentDomainID", "//currentURL")));
}).then(function(results) {
    // results is an array of results in order
});

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