如何使用promises为对象数组的每个元素进行ajax调用?

时间:2016-10-05 19:16:03

标签: javascript ajax promise iterable

我有这段代码:

       // _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);
                    });

                };

理解此代码的一些元素:

**** Ajax通话设置

  • url:sessionURL
  • data:要发送到服务器的数据是对模块的外部调用 queryServ.js和函数getAllUserDomainCommentsFunct 返回一个JSON对象。它需要这些参数才能工作: currentDomain,userID,currentDomain(再次),currentURL
  • type:text
  • contentType:text / plain
  • context:this

****评论是jsonObject smilar {id: "998", textOfcomment:"I commented this", target: "//targetID"}.

我想要做的是为数组的每个用户做一个ajax调用" _arrOfUsers"提取他在服务器上的所有评论;经过所有"提取"我需要获取所有结果(这是所有用户的所有注释)并在控制台中打印它们。订单对我的代码很重要,这就是我使用Promise的原因。

我在StackOverflow上的JSfiddle上找到了这个算法的结构,但它对我不起作用,因为它返回了一系列函数,我不明白为什么,可能是因为我'在我的职业生涯中从未使用过Promises。

提前感谢您,如果有不清楚的地方,请随时告诉我。

1 个答案:

答案 0 :(得分:3)

由于$.post()已经返回一个承诺而$.when()按顺序保存结果,因此无需在此处创建延迟。相反,你可以这样做:

$.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
    }
});

注意:我不太明白你试图用$.post()的参数做什么(你似乎已经构成了jQuery doc没有显示的一些参数)所以我稍微简化了一下,但是您可能需要调整那些$.post()参数以满足您的目的。

就个人而言,我鄙视$.when()以及它如何与jQuery ajax承诺交互(非常混淆使用)所以我会将ajax承诺强制转换为ES6承诺并使用Promise.all()(使用Bluebird如果需要较旧的浏览器支持,则为promise支持。)

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
});

或者,如果您包含Bluebird,您可以使用:

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
});