簡體   English   中英

順序AJAX請求處理和存儲

[英]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 );
}

您似乎希望代碼執行兩件事。

  1. 僅當返回前一台打印機的請求后,才請求下一台打印機的數據
  2. 僅在所有請求返回后才更新DOM。

不幸的是,你的代碼既不這些事情。 :(

$.each是一種迭代類似數組的事物的方法,但它不會等到請求返回后才繼續移動列表中的下一項。 Ajax請求是異步的,這意味着你給他們打電話,在你的代碼移動到下一個操作。 當他們這樣做,他們將回調無論是successerror的功能,但同時請求發生此代碼不會阻塞。

如果要觸發順序請求,則可以創建某種幫助程序功能,該功能可以使您遍歷數組,並且僅在知道第一個完成后才在數組的下一項上調用該函數。 如果要在它們全部完成后執行一些操作,則需要再執行一個函數,當數組中的所有項目都已處理完畢時,該函數將進行回調。

這是一個有關如何按順序執行異步操作的小示例。

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);
});

關鍵是您要在successerror回調中調用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM