2016-08-09 46 views
-1

Ich habe eine verschachtelte Funktion, die einige I/O durchführt und einen Rückruf aufruft, sobald sie mit den resultierenden Daten fertig ist. Etwas wie folgt aus:Bearbeiten von Daten in einer Callback-Funktion

function getStatus(returnCallback, errorCallback) { 
    sendRequest('someData', returnCallback, errorCallback) 
} 

wobei sendeanfrage() ist eine Funktion, die mit Hardware und ruft die returCallback mit den Daten interagiert, die es von der Hardware oder dem errorCallback, falls etwas schief gelaufen bekam. Mein Problem ist jetzt, dass die Daten, die die Hardware zurückgibt, eine wirklich lange Zeichenfolge ist, die aus verschiedenen Zahlen besteht, die verschiedene Parameter darstellen. Ich möchte die Daten bearbeiten, die dem returnCallback übergeben werden, und mit einer Eigenschaft für jeden Parameter erstellen und ein Objekt erstellen. Gibt es eine Möglichkeit, das zu tun? Ich habe bereits versucht mit async.waterfall

function getStatus(returnCallback, errorCallback) { 
     let returnArray = {}; 
     async.waterfall([ 
      function (callback) { 
       sendRequest('someData', callback, errorCallback); 
      }, 
      function (data, callback) { 
       returnArray.statusBits = data.slice(0, 6); 
       returnArray.faultBits = data.slice(7, 13); 
       returnArray.alertBits = data.slice(14, 20); 
       returnArray.pumpRotationSpeed = parseInt(data.slice(21, 26)); 
       returnArray.motorPower = parseInt(data.slice(27, 31)); 
       returnArray.frequencyConverterTemperature = parseInt(data.slice(36, 39)); 
       returnArray.pumpOperationTime = parseInt(data.slice(44, 48)); 
       callback(null, returnArray) 
      } 
     ], returnCallback(returnArray)); 

aber das tut nichts. Wie es aussieht, wird die zweite Funktion im Wasserfall nie aufgerufen. Dies könnte sein, da der Rückruf von der ersten Funktion ist nicht im Wasserfall wie erwartet strukturiert und es gibt mit Rückruf (Daten) statt Rückruf (null, Daten)

Antwort

1

In async.waterfall Rückruf, das erste Argument error sollten Sie auch auf das Ende des Wasserfalls warten, bevor Sie die Funktion verlassen. Der richtige Code wäre:

function getStatus(returnCallback, errorCallback) { 
    let returnArray = {}; 
    async.waterfall([ 
     function (callback) { 
      //First step 
      sendRequest('someData', function (data) { 
       //Everything is fine, continue 
       callback(null, data); 
      }, function (error) { 
       //Error, skip all remaining step, and handle the error 
       callback(error); 
      }); 
     }, 
     function (data, callback) { 
      //Second step 
      returnArray.statusBits = data.slice(0, 6); 
      returnArray.faultBits = data.slice(7, 13); 
      returnArray.alertBits = data.slice(14, 20); 
      returnArray.pumpRotationSpeed = parseInt(data.slice(21, 26)); 
      returnArray.motorPower = parseInt(data.slice(27, 31)); 
      returnArray.frequencyConverterTemperature = parseInt(data.slice(36, 39)); 
      returnArray.pumpOperationTime = parseInt(data.slice(44, 48)); 
      callback(null, returnArray) 
     } 
    //In normal case, error will be null, and the param will be the last passed to the callback of the last step 
    ], function (error, returnArray) { 
     //If there is a error (like error in step 1) 
     if(error) { 
      //Handle the error 
      errorCallback(error); 
     } else { 
      //No error, continue with the normal callback 
      returnCallback(returnArray); 
     } 
    }); 
} 
+0

danke das wies mich in die richtige Richtung –

+0

Gibt es tatsächlich eine Möglichkeit, die Tatsache, dass ich eine zweite Callback-Funktion, die für die Fehler verantwortlich ist, zu integrieren? Damit der Wasserfall gestoppt wird, wenn sendRequest einen Fehler zurückgibt? Etwas wie 'sendRequest ('someData', functon (Daten) {Rückruf (null, Daten)}, Funktion (Fehler) {Rückruf (Fehler, null)})' –

+0

Sie tun es nicht so mit Wasserfall, der Ziel ist es, am Ende des Wasserfalls zu gehen, indem entweder alle verbleibenden Schritte übersprungen werden, wenn Fehler auftreten, oder am Ende des Wasserfalls, nach Fehlern suchen und mit ihnen umgehen. – DrakaSAN

0

Was Sie tun möchten, ist

die Daten manipulieren, die für jeden Parameter an die returnCallback und erstellen und Objekt mit einer Eigenschaft gegeben ist.

Sie haben

function getStatus(returnCallback, errorCallback) { 
    sendRequest('someData', returnCallback, errorCallback) 
} 

Wenn ich verstanden, was Sie zu tun versuchen,

function getStatus(function(err, status) { 
    if (err) return new Error('Something went wrong'); 
    else sendRequest(status); 
} 
//get what you need here 
var status = ...) 

Hier wird die getStatus Funktion Start durch die Callback-Funktion in einem parallelen Prozess ausführt. Die Parameter status und err werden als Platzhalter im Speicher abgelegt. Zur gleichen Zeit macht der getStatus, was er tun muss, um den gewünschten Status abzurufen und als Variable zu speichern. Wenn das Lesen abgeschlossen ist, wird das Ergebnis innerhalb der Platzhalter des parallelen Prozesses platziert und die Ausführung ist beendet.

Diese asynchrone Methode kommt von der Tatsache, dass Sie Daten innerhalb der Hardware lesen und es einige Zeit braucht, um sie abzurufen. Der synchrone Weg würde die Aufgaben blockieren und darauf warten, dass alle Schritte abgeschlossen werden, während er asynchron erlaubt, nicht bei jedem Schritt zu blockieren, sondern die anderen Aufgaben zu starten, während er die vorherigen beendet.