2013-07-23 11 views
5

このWebサイトは、PINパッド付きCardReaderを管理するローカルサービスと接続しています。このデバイスを使用して完了することができる多くの異なる操作があります。相続人はその一つの例:jQueryを使用して連鎖AJAX呼び出しを管理する方法

  1. は、私は今の鎖に相互間のコールバックを使用しますが、前
  2. は、PIN番号
  3. リリースデバイス

を求めるデバイスをロックするので、 "ロック"や "リリース"のようなメソッドも使用する新しい操作があるので、コードを変更して、ステップ1と3のコードを再利用できるようにする必要があります。

私はこれをjQueryの約束で解決しようとしていましたが、これにはかなり新しいですが、どういうふうに動作するかは本当に分かりません。誰かが私に手を差し伸べることができる?

これは今使用しているコードの例です。私は例を簡単にするために、関数内からビジネスロジックを削除している:これはあなたのニーズに合うことができる

var CardReader = { 

    //////////////////// 
    // Different possible messages to the Card Reader 
    //////////////////// 

    lockDevice: function() { 
     this.makeAjaxCall("GET", "/LockDevice", this.lockDeviceCallback); 
    }, 

    getPin: function() { 
     this.makeAjaxCall("POST", "/getPin", this.getPinCallback); 
    }, 

    releaseDevice: function() { 
     this.makeAjaxCall("POST", "/Release", this.releaseDeviceCallback); 
    }, 

    ////////////////// 
    // Callbacks for each message to the Card Reader 
    ////////////////// 

    lockDeviceCallback: function(jqXHR, textStatus) { 
     if (textStatus !== "success") { return; } 
     this.getCardLogin(); 
    }, 

    getCardLoginCallback: function(jqXHR, textStatus) { 
     if (textStatus !== "success") { return; } 
     this.releaseDevice(); 
    }, 

    releaseDeviceCallback: function(jqXHR, textStatus) { 
     if (textStatus !== "success") { return; } 
     //End 
    }, 

    //////////////// 
    // Other methods 
    //////////////// 

    init: function() { 
     // UI BIndings 
     $(#button).on("click", this.logIn.bind(this)); 
    }, 

    logIn: function() { 
     this.lockDevice(); 
    }, 

    makeAjaxCall: function(callType, resource, callbackMethod) { 

     $.ajax({ 
      type  : callType, 
      url  : "http://localhost:1337" + resource, 
      cache  : false, 
      dataType : "json", 
      contentType: "application/json", 
      context : this, 
      complete : callbackMethod 
     }); 
    } 
}; 

答えて

1

でも私はここに完全にあなたの問題を理解することはよく分かりません。

ここで重要な点は、ajaxメソッドのコールバックを整理しているようです。

は、これらのメソッドを作成します:

logIn: function logIn() { 
     var calls = ["lockDevice", "getCardLogin", "releaseDevice"]; 
     this._when(calls, arguments.callee.name); 
    }, 
    getPinOnly: function getPinOnly() { 
     var calls = ["getPin"]; 
     this._when(calls, arguments.callee.name); 
    }, 

DEMO

COMPLETE CODE:

var CardReader = { 

    //////////////////// 
    // Different possible messages to the Card Reader 
    //////////////////// 

    lockDevice: function() { 
     return this.makeAjaxCall("GET", "/LockDevice", this.lockDeviceCallback); 
    }, 
    getCardLogin: function() { 
     return this.makeAjaxCall("POST", "/getCardLogin", this.getCardLoginCallback); 
    }, 
    getPin: function() { 
     return this.makeAjaxCall("POST", "/getPin", this.getPinCallback); 
    }, 

    releaseDevice: function() { 
     return this.makeAjaxCall("POST", "/Release", this.releaseDeviceCallback); 
    }, 

    ////////////////// 
    // Callbacks for each message to the Card Reader 
    ////////////////// 

    lockDeviceCallback: function (jqXHR, textStatus) { 
     console.log("lockDeviceCallback"); 
     if (textStatus !== "success") { 
      return; 
     } 
    }, 

    getCardLoginCallback: function (jqXHR, textStatus) { 
     console.log("getCardLoginCallback"); 
     if (textStatus !== "success") { 
      return; 
     } 
    }, 
    getPinCallback: function (jqXHR, textStatus) { 
     console.log("getPinCallback"); 
     if (textStatus !== "success") { 
      return; 
     } 
    }, 

    releaseDeviceCallback: function (jqXHR, textStatus) { 
     console.log("releaseDeviceCallback"); 
     if (textStatus !== "success") { 
      return; 
     } 
     //End 
    }, 

    //////////////// 
    // Other methods 
    //////////////// 

    init: function() { 
     // UI BIndings 
     $('#btn_login').on("click", $.proxy(this.logIn, this)); 
     $('#btn_getPinCallback').on("click", $.proxy(this.getPinOnly, this)); 
    }, 
    _nextCall: function (deferreds, method) { 
     if (deferreds.length) this._when(deferreds, method); 
     else console.log(method + " SUCCESS"); 
    }, 
    _when: function (calls, method) { 
     var $promise = $.when(this[calls[0]]()) 
     $promise.then(function() { 
      calls.splice(0, 1); 
      this._nextCall(calls, method); 
     }, function() { 
      console.log(method + " FAILED on: " + calls[0]); 
     }); 
    }, 
    logIn: function logIn() { 
     var calls = ["lockDevice", "getCardLogin", "releaseDevice"]; 
     this._when(calls, arguments.callee.name); 
    }, 
    getPinOnly: function getPinOnly() { 
     var calls = ["getPin"]; 
     this._when(calls, arguments.callee.name); 
    }, 

    makeAjaxCall: function (callType, resource, callbackMethod) { 

     return $.ajax({ 
      type: callType, 
      url: "/echo/json", // + resource, 
      cache: false, 
      dataType: "json", 
      contentType: "application/json", 
      context: this, 
      success: callbackMethod 
     }); 
    } 
}; 

CardReader.init(); 
1
_nextCall: function (deferreds, method) { 
     if (deferreds.length) this._when(deferreds, method); 
     else console.log(method + " SUCCESS"); 
    }, 
    _when: function (calls, method) { 
     var $promise = $.when(this[calls[0]]()) 
     $promise.then(function() { 
      calls.splice(0, 1); 
      this._nextCall(calls, method); 
     }, function() { 
      console.log(method + " FAILED on: " + calls[0]); 
     }); 
    }, 

は、例えば同じようにそれを使用してくださいあなたはそのような何かを行うことができますもっと充実した約束ライブラリーを使用する。次を参照してください。https://github.com/kriskowal/q コードのスタイルと可読性を大幅に向上させるので、少し時間をかけて検討する価値があります。それは約束を返すので、基本的には、各業務機能を書くことができますので、以下のようなもの: -

function myBusinessFunction(params) { 
    var deferred = Q.defer(); 
    .... 
    doSomeAsyncFunction(params,function(error,result) { 
     if (error) { 
      deferred.reject(new Error(error)); //pass the error on 
     } else { 
      deferred.resolve(result); 
     } 
    }); 
    return deferred.promise; 
} 

だから何ここで起こっていると、その繰延を作成内側にあなたは、関数を作成しない各非同期操作のためにありますそれを返す。タイムアウトやエラーや結果が出たら、deferred.rejectやdeferred.resolveを呼び出します。

あなたのコードにそれ以外を使用すると、あなたは、次のようなものネストされた関数の多くを持っているし、あなたの全体的なアルゴリズムのコードを作成し、コールバック地獄を避けることができます -

Q.fcall(promisedStep1) 
.then(promisedStep2) 
.then(promisedStep3) 
.then(promisedStep4) 
.then(function (value4) { 
    // Do something with value4 
}) 
.catch(function (error) { 
    // Handle any error from all above steps 
}) 
.done(); 

これは密接に試しに似ているが...手頃な手順のプログラミングをキャッチしますが、実際には非同期プロセスを扱っています。約束を棄ててコールすると、コントロールフローがcatch関数に渡され、プログラミングが大幅に簡略化されます。

ライブラリーには多くの追加機能がありますので、実行中のステップを並行して処理できるようになります。ドキュメントをチェックアウトするだけで十分な価値があります。

1

は、あなたのAjaxの呼び出しでasync: falseを試してみてください。まず、Ajax呼び出しを完了してから、他のステートメントを実行します。

makeAjaxCall:関数(CALLTYPE、リソース、callbackMethod){

$.ajax({ 
     type  : callType, 
     url  : "http://localhost:1337" + resource, 
     cache  : false, 
     dataType : "json", 
     contentType: "application/json", 
     context : this, 
     async :false, 
     complete : callbackMethod 
    }); 
} 
-1
 jQuery.support.cors = true; 

     $.ajax({ 
      type: "POST", 
      contentType: "application/json; charset=utf-8", 
      datatype: "json",    
      async :false, 
      url: "http://yourHost:portnumeber/ServiceName/LockDevice", 
      success: 
     lockDeviceCallback, 
      error: 
     function (XmlHttpRequest, textStatus, errorThrown) { 
      errorHandler(XMLHttpRequest); 
     } 
     });    
関連する問題