0

Webインターフェイスを備えたプリンターからデータを順番にプルするスクリプトを作成しようとしています。大規模なローカルネットワークには500を超えるネットワークがあるため、前のネットワークが(成功したかどうかにかかわらず)戻ったら、次のネットワークに呼びかけたいと思います。コールバックに頭を悩ませるのに苦労しています...それが最善の解決策である場合。

これが私が現在立っているところです(親切にしてください、これはjQuery / Javascriptの紹介であり、これはプルーフテストです)。また、結果の呼び出しから配列を構築する方法はありますか?私がJavascriptに目を向けた理由は、PHPを実行時間で動作させることができなかったためです。

ああ、あなたはASYNCを見るでしょう:私がw / falseを試したが、それが機能しなかった(何も返さない)という理由だけでtrue。

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

2 に答える 2

0

コードに実行させたいことが2つあるようです。

  1. 前のプリンターの要求が戻ったときにのみ、次のプリンターのデータを要求します
  2. すべての要求が返された後でのみ、DOMを更新します。

残念ながら、あなたが持っているコードはこれらのことのどちらもしません。:(

$.eachは配列のようなものを反復処理する方法ですが、リスト内の次の項目に移動する前に、要求が戻るまで待機しません。ajaxリクエストは非同期で発生します。つまり、リクエストを呼び出して、コード内の次の操作に進みます。それらが完了すると、successまたはerror関数のいずれかをコールバックしますが、要求が発生している間、このコードがブロックされることはありません。

シーケンシャルリクエストを実行したい場合は、配列をループできるようなヘルパー関数を作成し、最初のアイテムが完了したことがわかっている場合にのみ、配列内の次のアイテムで関数を呼び出すことができます。すべてが終了したときに何らかのアクションを実行する場合は、配列内のすべてのアイテムの処理が完了したときにコールバックするもう1つの関数が必要です。

これは、非同期処理を順番に実行する方法の小さな例です。

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

重要なのは、コールバックとコールバックdoneで関数を呼び出していることです。これは、非同期操作が終了したことを関数に通知します。次の操作を開始するか、完了した場合またはエラーが発生した場合は関数を呼び出す必要があります。successerrordoAsyncStuffSequentiallyfinal

于 2012-11-13T22:14:42.253 に答える
0

サーバー側の何かがおそらくこのタスクに適しているという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);
      }
    });
  }
}
于 2012-11-13T22:30:45.377 に答える