异步ajax调用的java脚本闭包

时间:2017-01-20 09:53:44

标签: javascript ajax loops

我有下面的数据和javascript两个循环和ajax来获取数据。 两个循环与i j值一起正常工作。但是如果我在内部循环中添加ajax,则请求不会按顺序进行。我需要在循环序列中获取数据。我们怎样才能做到这一点?

var final = {};
final.reports = ['a','b','c']
final.clients = ['x','y']
final.reportDataJson = [];

for(var i=0;i<final.reports.length;i++){
        (function(i,reactthis){

            for(var j=0;j<final.clients.length;j++){
                (function(i,j,final){
                    console.log(i+" "+j+" "+final.clients[j])
                    // this shows correct i j values
                    $.ajax({
                        url: url,
                        cache: false,
                        success: function(html) {
                            var reportResponse = {
                                reportname : final.reports[i],
                                clientname : final.clients[j],
                                reporthtml : html,
                                reportgraph : ''
                            }
                            final.reportDataJson.push(reportResponse)
                            //console.log(i,j)
                            if( i == final.reports.length-1 && j == final.clients.length-1){

                                console.log(final.reportDataJson);

                            }
                        },
                        error: function(xhr, status, err) {
                            if( i == final.reports.length-1 && j == final.clients.length-1){
                            }
                        }
                    })              

                })
            }


        })(i,final);
    }

1 个答案:

答案 0 :(得分:0)

您可以使用$.ajax返回Promise的事实 - $.when - 等待一些Promises并按顺序返回已解析的值!

var final = {};
final.reports = ['a', 'b', 'c'];
final.clients = ['x', 'y'];
final.reportDataJson = [];

$.when.apply($, [].concat.apply([], final.reports.map(function(report) {
    return final.clients.map(function(client) {
        return $.ajax({
            url: url,
            cache: false
        }).then(function(results) {
            var html = results[0];
            // results[0] is same as success: html argument
            // results[1] is textStatus
            // results[2] is jqXHR
            return {
                reportname: report,
                clientname: client,
                reporthtml: html,
                reportgraph: ''
            };
        });
    })
}))).then(function() {
    final.reportDataJson = [].slice.call(arguments);
    console.log(final.reportDataJson);
});

使用$ .when.apply,因为$ .when将参数1..n作为承诺

使用[] .concat.apply来“展平”由嵌套.map的

返回的数组数组

使用原生承诺

会更容易一些
Promise.all([].concat.apply([], final.reports.map(function(report) {
    // code unchanged from above ....
}))).then(function(results) {
    final.reportDataJson = results;
    console.log(final.reportDataJson);
});

Promise.all接受一系列promises,并且它的.then回调接收一个参数,这些承诺的结果数组

为了ES2015 +善良

Promise.all([].concat.apply([], final.reports.map(report => final.clients.map(client => $.ajax({
    url: url,
    cache: false
}).then(([html, status, jqXHR]) => ({
    reportname: report,
    clientname: client,
    reporthtml: html,
    reportgraph: ''
})))))).then(results => console.log(final.reportDataJson = results));