简体   繁体   English

根据前一个ajax调用返回的数据执行未知数量的并行ajax调用

[英]Executing unknown number of parallel ajax calls based on data returned by a previous ajax call

I have a built a php backend which returns a JSON object (effectively a 2D array, I can reference it as json[0][0] for example, I don't know why though, I did not parse the JSON object) of information(train number, days it runs on etc) on trains between two stations. 我有一个PHP后端,它返回一个JSON对象(实际上是一个2D数组,我可以引用它作为json[0][0]例如,我不知道为什么,但我没有解析JSON对象)在两个车站之间的火车上的信息(列车编号,运行天数等)。

Now what I want to query the availability of each train. 现在我想查询每列火车的可用性。 I already have the php script for that (which returns a JSON object as well, giving the availability of the specified date as well as the next 5 days.). 我已经有了php脚本(它还返回一个JSON对象,提供指定日期以及接下来5天的可用性。)。

This availability php script requires some input which is present as the first element of every nested(wrong term to use ?) array eg : json[0][0], json[1][0], json[2][0] if 3 trains are returned 这个可用性PHP脚本需要一些输入作为每个嵌套(使用的错误术语?)数组的第一个元素,例如: json[0][0], json[1][0], json[2][0]如果有3列火车返回

I want this information returned as a response to parallel ajax calls. 我希望这些信息作为对并行ajax调用的响应而返回。 In the end I want to create a table based on these responses. 最后,我想根据这些响应创建一个表。 My problems are: 我的问题是:

  1. Since I don't know the number of trains which will returned before hand, hence the number of parallel ajax calls to be made, how do I code this portion ? 由于我不知道预先返回的列车数量,因此需要进行并行ajax调用的次数,我该如何编码这部分?
  2. Best way to make parallel calls seems to be $.when, how do I use it in this problems ? 进行并行呼叫的最佳方式似乎是$。但是,如何在这个问题中使用它?

I have just begun coding the function, and have something like this, yes I am an utter novice with JS and jQuery : 我刚刚开始编写函数,并且有类似的东西,是的,我是JS和jQuery的全新手:

$(document).ready(function() {
$("form").submit(function(){    
    event.preventDefault();

    $.ajax({
      //type: "POST",
      url: "./trains_bw_stations.php",
      dataType: 'json',
      data: { source: $('input[name*="src"]').val(), destination: $('input[name*="dstn"]').val(), 
                day: $('input[name*="day"]').val(), month: $('input[name*="month"]').val(), cl: $('input[name*="cl"]').val()  }
    })
      .done(function(trains) {
        console.log(trains)
        var requests = [], allData = {};

        for (var i = 0; i < trains.length; i++) {
            console.log(trains[i][0]);
            requests.push($.ajax({
                url: './availability.php', 
                dataType: 'json',
                data: { 
                        day: $('input[name*="day"]').val(), month: $('input[name*="month"]').val(),lccp_trndtl: trains[i][0]  }
                // success: function(data) {
                //  console.log(data);
                //     allData[''+i] = data;

            }).done(function(data) {
                    console.log(data);
                    allData[i] = data})
            );
        }

        $.when.apply(requests).then(function() {

            console.log(allData) // this is line 41

            }
            // all requests have completed
            // allData array now contains the data from all the requests
            // put your processing logic in here...
        });
    });
    });
    });

allData remains empty ! allData仍为空! console output : 控制台输出:

XHR finished loading: GET "http://localhost/irl_poster/trains_bw_stations.php?source=ndls&destination=hyb&day=7&month=8&cl=SL". jquery-2.1.1.min.js:4
[Array[15], Array[15], Array[15]]
 ajaxRequests.js:19
12650NZM KCG YYYNYNYYA ajaxRequests.js:23
12724NDLSHYB YYYYYYYYA ajaxRequests.js:23
12722NZM HYB NYYYYYYYA ajaxRequests.js:23
Object {} ajaxRequests.js:41
XHR finished loading: GET "http://localhost/irl_poster/availability.php?day=7&month=8&lccp_trndtl=12650NZM+KCG+YYYNYNYYA". jquery-2.1.1.min.js:4
Object {0: Array[4], 2: Array[4], 4: Array[4], 6: Array[4], 8: Array[4], 10: Array[4]}
 ajaxRequests.js:34
XHR finished loading: GET "http://localhost/irl_poster/availability.php?day=7&month=8&lccp_trndtl=12724NDLSHYB+YYYYYYYYA". jquery-2.1.1.min.js:4
Object {0: Array[4], 2: Array[4], 4: Array[4], 6: Array[4], 8: Array[4], 10: Array[4]}
 ajaxRequests.js:34
XHR finished loading: GET "http://localhost/irl_poster/availability.php?day=7&month=8&lccp_trndtl=12722NZM+HYB+NYYYYYYYA". jquery-2.1.1.min.js:4
Object {0: Array[4], 2: Array[4], 4: Array[4], 6: Array[4], 8: Array[4], 10: Array[4]}

You have an error in your $.when.apply call - it needs an initial context parameter, typically $ 你的$.when.apply调用中有一个错误 - 它需要一个初始上下文参数,通常$

Your code also suffers the common problem of using the loop variable i from inside an asynchronous callback at which point it no longer retains its original value and the results all end up in allData[trains.length + 1] 您的代码也遇到了在异步回调中使用循环变量i的常见问题,此时它不再保留其原始值,结果全部以allData[trains.length + 1]

So, instead of trying to accumulate allData[i] in the .done callback you can remove that .done call altogether, and then within the .when().then() callback you can use the arguments array to access the individual results, which will automatically appear in the correct order: 因此,不是试图在.done回调中累积allData[i] ,而是可以完全删除该.done调用,然后在.when().then()回调中,您可以使用arguments数组来访问单个结果,它将自动以正确的顺序出现:

$.when.apply($, requests).then(function() {

    // convert the arguments array, where each argument is in the form
    // [data, textStatus, jqXHR], into an array of just the data values
    var allData = [].map.call(arguments, function(arg) {
        return arg[0];
    });

    ...
});

The initial request loop can also be slightly simplified using Array.prototype.map : 使用Array.prototype.map也可以略微简化初始请求循环:

var requests = trains.map(function(train) {
    // no "i" variable needed - use "train" instead of "train[i]"
    return $.ajax({
        ...
    });
});

You are correct that you need to use $.when , although your syntax is a little off. 你是正确的,你需要使用$.when ,虽然你的语法有点偏。 Try this: 尝试这个:

.done(function(json) {
    var requests = [], allData = [];

    // loop over your result, amend as needed
    for (var i = 0; i < json.length; i++) {
        requests.push($.ajax({
            url: 'foo.html', // build as needed using properties of json
            success: function(data) {
                allData.push(data);
            }
        }));
    }

    $.when.apply(requests).then(function() {
        // all requests have completed
        // allData array now contains the data from all the requests
        // put your processing logic in here...
    });
});

If you need to maintain the order of the data received, you could change the allData variable to an object, keyed by the index of the loop: 如果需要维护接收数据的顺序,可以将allData变量更改为一个对象,由循环索引键入:

// note: amended lines only
var requests = [], allData = {};

success: function(data) {
    allData[i] = data;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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