Async: die Wasserfallkette unterbrechen, ohne einen Fehler zu machen

Erstellt am 15. Feb. 2011  ·  8Kommentare  ·  Quelle: caolan/async

Mir wurde gesagt, dass ich meinen Code umgestalten muss, der einen asynchronen Wasserfall verwendet. Ich habe es hauptsächlich verwendet, weil ich mehrere verkettete Funktionen hatte, die zu tief gingen, und ich eine Funktion wiederverwenden wollte usw. An einer Stelle in der Kette gibt es eine Bedingung, die nicht unbedingt eine Fehlerbedingung ist, die ich aber nicht tue Ich möchte den Rest der Wasserfallkette weitergeben, weil es nutzlos ist - sagen wir zum Beispiel, ich habe eine Abfrage durchgeführt und es gibt keine Ergebnisse, und das ist kein Fehler, ich möchte nicht ohne Ergebnisse ganz nach unten propagieren. Wenn ich dies ohne Async tun würde, hätte ich vermutlich einen "letzten" Rückruf, der aufgerufen werden könnte, um aus der Kette auszubrechen, ohne explizit einen Fehler auszulösen. Diese Funktionalität scheint in Wasserfall nicht vorhanden zu sein. Gibt es eine Möglichkeit das sauber zu machen? Die einzige Möglichkeit, die ich sehen kann, besteht darin, einen speziellen Fehler auszulösen und diesen dann beim letzten Rückruf zu behandeln, um einen Nicht-Fehler zurückzugeben.

Hilfreichster Kommentar

Persönlich benötige ich solche Funktionen und denke, dass sie der Kernbibliothek hinzugefügt werden sollten.

Hier ist mein Helfer-Workaround, wenn jemand interessiert ist ...

exports.breakWaterfall = function(tasks, callback){
    async.waterfall(tasks, function(){
        if(arguments[0] === 'break'){
            arguments[0] = null;
        }
        callback.apply(null, arguments);
    });
}

Wenn Sie innerhalb einer Aufgabe bis zur letzten Funktion unterbrechen müssen, rufen Sie den Callback einfach wie folgt auf: done('break', other, arguments); .

Der Helfer erkennt nur 'break' und mutiert die Argumente, damit es für den Rest Ihres Codes nicht wie ein Fehler aussieht.

Alle 8 Kommentare

Hallo,

wahrscheinlich hast du dein Problem mittlerweile gelöst, übrigens ist dies mein Ansatz:

var flow = [
    async.apply(...),
    // ...
];

async.waterfall(flow, function (err) {
    if (err === 'ok') return;
    // handle error
});

Wenn eine Funktion einen Callback mit err = 'ok' aufruft, wird er vom letzten Callback des Wasserfalls abgefangen.

Ich habe ein ähnliches Problem und füge einen Callback-Wrapper hinzu (den ich vermeiden könnte), nur um zu überprüfen, ob es sich bei jedem Wasserfall, den ich verwende, um einen Fehler handelt oder nicht. Es ist nicht so sauber, wenn es mehr als einen Wasserfall gibt.
Kann die Callback-Funktion selbst eine andere Eigenschaft namens 'final' haben, die Leute aufrufen können, um zum Ende zu gelangen?
Etwas wie

function search (cond, callback) {
  async.waterfall([function (cb) {
      db.get(cond, cb);
    },
    function (res, cb) {
      if (!res || !res.length)
        return cb.final();
      //do something useful
    }
  ], callback);
}

Ich muss den Rückruf nicht umschließen und er könnte mit dem Rest des Programms verkettet werden.

@caolan gibt es etwas, das dir an @jnordberg- Pull-Request nicht gefällt? Und wenn ja, kann ich etwas tun, damit dieser Pull-Request akzeptiert wird?

@tax : springen können , indem wir 'error' = true wie

async.waterfall([Funktion (Rückruf) {
Rückruf (null); // <--- gehe zum nächsten fn
},
Funktion (Rückruf) {
Rückruf (wahr); // <--- zum letzten fn springen
},
Funktion (Rückruf) {
Rückruf (null); // <--- diese fn wird nicht aufgerufen
}
], Ruf zurück);

@tot2ivn danke für den Tipp!

Wenn Sie den Fehler setzen, ist das Ergebnis jedoch leer.

var async = require('async');

async.waterfall( [
  function( callback ){
    console.log('one');
    callback( null );
  },

  function( callback ){
    console.log('two');
    callback( true, 'more info' );
  },

  function( callback ){
    console.log('three');
    callback( null );
  }
], function(err, result){
  console.log( err, result );
} );

// RESULT
// one
// two
// true undefined

Angesichts des Kommentars von @caolan zum Schließen von Pull Request #85 sollte dieses Problem wahrscheinlich geschlossen werden

Persönlich benötige ich solche Funktionen und denke, dass sie der Kernbibliothek hinzugefügt werden sollten.

Hier ist mein Helfer-Workaround, wenn jemand interessiert ist ...

exports.breakWaterfall = function(tasks, callback){
    async.waterfall(tasks, function(){
        if(arguments[0] === 'break'){
            arguments[0] = null;
        }
        callback.apply(null, arguments);
    });
}

Wenn Sie innerhalb einer Aufgabe bis zur letzten Funktion unterbrechen müssen, rufen Sie den Callback einfach wie folgt auf: done('break', other, arguments); .

Der Helfer erkennt nur 'break' und mutiert die Argumente, damit es für den Rest Ihres Codes nicht wie ein Fehler aussieht.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen