[英]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: 我的问题是:
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.