2016-06-22 11 views
4

Ich benutze async.js für meine node.js App. Ich brauche Hilfe beim Lösen des folgenden Problems.Async.js Designmuster

Nehmen wir an, ich habe eine folgende aysnc js-Serie-Funktion.

async.waterfall([ 
    function getDataFromDB(request, response, callback){ ... }, 
    function someOperationOnDBData(dbData, response, callback){ ... }, 
    function renderSomeFlow(evaluatedData, response, callback){ ... } 
]); 

Ich habe drei Funktionen in der oben genannten Reihenfolge aufgerufen. Ich bekomme Daten von getDataFromDB und übergebe an someOperationOnDBData und so weiter.

Angenommen, ich brauche eine weitere Operation zwischen getDataFromDB und , aber übergeben Sie DBData immer noch weiter. ZB:

async.waterfall([ 
    function getDataFromDB(request, response, callback){ ... }, 
    function extraOperation(dbData, response, callback) {...} 
    function someOperationOnDBData(dbData, extraOperationData, response, callback){ ... }, 
    function renderSomeFlow(evaluatedData, response, callback){ ... } 
]); 

Hier ein einzelner Schritt in der Mitte Addition der Funktionsdefinitionen verändert und ich brauche auch dbData in extraOperation passieren nur darauf, es zu someOperationOnDBData. Wenn ich ein anderes Modul in der Mitte anrufe, ist es eventuell nicht möglich, den Parameter zu ändern, um Daten weiterzuleiten.

Wie löst man dieses Problem der Übergabe von Daten zwischen Funktionen in async.js ohne Weiterleitung von Daten in mittleren Funktionen? Refactoring-Funktionen bei jedem neuen Schritt sind nicht möglich. Was ist das Entwurfsmuster für die Lösung dieser Art von Problem?

+0

ist nur ein wenig off-topic, aber ich denke, dass Sie für Versprechungen brauchen. – Hitmands

+0

@Hitmands könntest du bitte mehr ausarbeiten? Wie werden Versprechen dieses Problem lösen? – dejavu

+0

@dejavu Versprechen erfordern Refactoring Ihrer Methoden, wie Sie nicht Wasserfall mit nativen Promises. Sie können jedoch ein einzelnes Objekt durch die Kette senden, die Sie bearbeiten und hinzufügen. Dann ändern Sie nicht die Funktionssignaturen in jeder Methode in dieser Kette. Solange Sie keine widersprüchlichen Eigenschaftsnamen haben. Plus macht es komplexen Fluss viel einfacher als Rückrufe und flacht die Kette ab. Keine Callback-Hölle mehr. Ich würde jedes Mal Versprechen über Rückrufe wählen. – ste2425

Antwort

4

Mit waterfall müssen Sie die Daten übergeben - Sie können einen Wasserfall in der Mitte nicht stoppen :). Es gibt Alternativen, die Sie möglicherweise verwenden möchten, z. B. auto, mit der Sie angeben können, welche Funktionen von den Ergebnissen anderer Funktionen abhängen, und async bestimmt die beste Reihenfolge für die Ausführung.

Ich finde die Syntax von auto ein wenig peinlich, aber es tut, was Sie brauchen. Hier ein Beispiel:

async.auto({ 
    db: function getDataFromDB(callback){ ... }, 
    extra: ['db', function extraOperation(results, callback) {...}], 
    some: ['db', function someOperationOnDBData(results, callback){ ... }], 
    render: ['some', 'db', function renderSomeFlow(results, callback){ ... }] 
}); 
0

ich gefunden habe, dass Ihre Funktionen mit Pfeil Funktionen currying ist ein Weg rund um dieses Problem:

const someOperationOnDBData = extraOperationData => (dbData, response, callback) => { 
    // do your function work 
}; 

async.waterfall([ 
    function getDataFromDB(request, response, callback){ ... }, 
    function extraOperation(dbData, response, callback) {...} 
    someOperationOnDBData(extraOperationData)(dbData, response, callback), 
    function renderSomeFlow(evaluatedData, response, callback){ ... } 
]); 

Viele gute Beispiele dafür, wie JavaScript-Funktionen Curry auf Medium.com