[英]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.