[英]Sequential AJAX request processing and storage
我正在尝试编写脚本以从具有Web界面的打印机中顺序提取数据。 大型的本地网络上有500多个,因此,我想在上一次返回(无论成功与否)后都调用下一个的原因。 我很难绕过回调...如果这是最好的解决方案。
这就是我目前的立场(请亲爱的,这是我对jQuery / Javascript的简介,这是一个证明测试)。 另外,有没有一种方法可以根据结果调用来构建数组? 我之所以使用Javascript是因为我无法让PHP随执行时间而变化。
哦,您将在下面看到ASYNC:true,仅是因为我尝试了w / false,但它不起作用(返回任何内容)。
function pingDevice(prnList) {
prnList = ["www.google.com", "amazon.com", "facebook.com", "as923f.com"];
document.getElementById("myDiv").innerHTML="please wait...";
$(prnList).each( function(index,printer) {
$.ajax({
type: "GET",
dataType: "html",
url: "pingTest.php?ping="+printer,
async: true,
success: function (data) {
$('#myDiv').append( $('<div class="prn"></div>').html(data) );
$prnResults[printer] = data;
},
error: function () {
$prnResults[printer] = data;
}
});
});
$('#myDiv').append( $('<div class="prn"></div>').$prnResults );
}
您似乎希望代码执行两件事。
不幸的是,你的代码既不这些事情。 :(
$.each
是一种迭代类似数组的事物的方法,但它不会等到请求返回后才继续移动列表中的下一项。 Ajax请求是异步的,这意味着你给他们打电话,在你的代码移动到下一个操作。 当他们这样做,他们将回调无论是success
或error
的功能,但同时请求发生此代码不会阻塞。
如果要触发顺序请求,则可以创建某种帮助程序功能,该功能可以使您遍历数组,并且仅在知道第一个完成后才在数组的下一项上调用该函数。 如果要在它们全部完成后执行一些操作,则需要再执行一个函数,当数组中的所有项目都已处理完毕时,该函数将进行回调。
这是一个有关如何按顺序执行异步操作的小示例。
var data = ['1', '2', '3', '4'];
function doAsnycStuffSequentially(data, callback, final) {
var i = 0,
length = data.length;
function getNextItem() {
callback(data[i++], done);
}
function done(err) {
if (err) {
return final(err);
}
// Only call the final function if there is an error or if we are done looping.
if (i >= data.length) {
return final();
}
getNextItem();
}
getNextItem();
}
doAsyncStuffSequentially(data, function(item, done) {
console.log("item is ", item);
// simulate some asynchronous operation
setTimeout(done, 1000);
}, function(err) {
console.log("done with all and error is", err);
});
要将这种模式应用于您自己的代码,只需定义自己的回调函数,该回调函数将在数组中的每个项目上调用,如下所示:
var printerData = {},
printerNames = ['hurp', 'durp'];
function getPrinterInfo(printerName, done) {
$.ajax({
type: "GET",
dataType: "html",
url: "pingTest.php?ping="+printer,
success: function (data) {
printerData[printerName] = data;
done();
},
error: function (jqXHR, textStatus, err) {
console.error("error getting printer status", err);
done(err);
}
});
}
doAsyncStuffSequentially(printerName, getPrinterInfo, function(err) {
console.log("done getting printer names and error was", err);
console.log("printerData is", printerData);
});
关键是您要在success
和error
回调中调用done
函数。 这标志着该doAsyncStuffSequentially
是一个异步操作已完成功能,它应该要么开始下一个,或致电final
功能,如果我们完成或发生错误。
尽管我同意Sonesh的观点,即服务器端的某个东西可能更适合此任务,但是这里对您的代码进行了一些调整(应该尝试)。
基本上,将实际的ajax调用嵌套在其自己的函数pingNext
。 每次调用返回时,都会为prnList
数组中的下一项再次调用该函数。 另外,我调整了代码以对ajax调用使用jQuery的类似于promise的语法。 通常,它是链接ajax调用的一种更好的语法(尽管此处并非完全必要)
function pingDevice(prnList) {
prnList = ["www.google.com", "amazon.com", "facebook.com", "as923f.com"];
document.getElementById("myDiv").innerHTML="please wait...";
var i = 0;
function pingNext(j) {
$.ajax({
type: "GET",
dataType: "html",
url: "pingTest.php?ping="+prnList[j],
async: true,
}).done(function(data) {
// stuff to do when successfull
$('#myDiv').append( $('<div class="prn"></div>').html(data) );
}).fail(function(data) {
// stuff to do on error
}).always(function(data){
// stuff to do no matter what
// stash the result
$prnResults[printer] = data;
// if there are more items in the prnList array, repeat
if (i < prnList.length) {
i++;
pingNext(i);
}
});
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.