2013-07-23 5 views
5

Ich habe diese Website, die sich mit einem lokalen Dienst verbindet, der einen CardReader mit einem PIN-Pad verwaltet. Es gibt viele verschiedene Operationen, die mit diesem Gerät ausgeführt werden können. ein Beispiel für eine von ihnen Heres:So verwalten Sie verkettete AJAX-Anrufe mit jQuery

  1. Sperren des Geräts
  2. für PIN-Nummer fragen
  3. Ausrückvorrichtung

Bevor ich zur Kette verwendet, um die Rückrufe untereinander, aber jetzt, da Es gibt neue Operationen, die auch Methoden wie "lock" und "release" verwenden. Ich muss meinen Code ändern, damit der Code für Schritt 1 und 3 wiederverwendbar ist.

Ich habe versucht, dies mit jQuery Versprechen zu lösen, aber ich bin ganz neu in dieser und ich habe noch wirklich herausgefunden, wie sie funktionieren. Kann mir jemand helfen?

Dies ist ein Beispiel für den Code, der jetzt verwendet wird. Ich habe die Geschäftslogik aus dem Innern der Funktionen entfernt, um das Beispiel zu vereinfachen:

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

Antwort

1

Dies könnte Ihre Bedürfnisse paßt auch ich bin nicht sicher, voll hier Ihre problematisch zu verstehen.

Der wichtige Punkt hier scheint Reihenfolge auf Ajax-Methode Rückrufe zu halten. Man könnte so etwas tun:

Erstellen Sie diese Methoden:

_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]); 
     }); 
    }, 

Verwenden Sie es wie die z:

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

Verwenden Sie eine umfassendere Bibliothek für Versprechungen. Schauen Sie sich auf: https://github.com/kriskowal/q Es lohnt sich ein wenig Zeit nehmen, zu verstehen, wie es in beträchtlichem Ausmaß die Art und die Lesbarkeit des Codes verbessert. Grundsätzlich können Sie jede Geschäftsfunktion schreiben, so dass es ein Versprechen gibt, so etwas wie folgt aus: -

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

Also, was ist denn hier los ist für jeden Asynchron-Operation, die Sie eine Funktion zu tun erstellen, im Inneren, dass eine latente erstellen und gib es zurück. Sobald Sie ein Timeout oder einen Fehler oder ein Ergebnis zu erhalten, dann rufen Sie deferred.reject oder deferred.resolve.

Mit dieser Ergänzung zu Ihrem Code können Sie dann Rückruf Hölle vermeiden, wo Sie viele verschachtelte Funktionen haben und erstellen Sie Ihre Gesamtalgorithmus Code etwa wie folgt: -

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

Dies ähnelt stark dem Versuch ... Verfolgen Sie die prozedurale Stil-Programmierung, die Ihnen so vertraut ist, aber Sie beschäftigen sich tatsächlich mit asynchronen Prozessen. Wenn Sie das auf dem Versprechen ablehnen rufen dann Fluss steuern, um die Fang-Funktion übergeben wird die Programmierung erheblich vereinfacht.

Es gibt viele zusätzliche Funktionen und Features in der Bibliothek, so dass Sie mit Laufschritte parallel und so weiter bewältigen können.Überprüfen Sie die Dokumente, es ist es wert.

1

async: false mit Ajax-Aufruf Versuchen. Dies beendet zuerst Ihren Ajax-Aufruf und führt dann andere Anweisungen aus.

makeAjaxCall: Funktion (Calltype, Ressourcen- 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); 
     } 
     });