2013-03-19 15 views
8

Ich möchte wissen, welche der beiden Methoden besser sind, wenn es um asynchronen Code in JavaScript geht. Ich möchte verstehen, welche Methode zu saubereren Code führt. Ich werde mit Versprechungen verwendet und sie scheinen flexibler als der asynchrone Ansatz (https://github.com/caolan/async).task.js Generatoren/Versprechen vs async Callbacks

Ich weiß auch über die Task.js-Bibliothek (http://taskjs.org/), aber dies beruht auf dem Yield-Schlüsselwort, das Teil von Ecmascript Harmony ist.

+2

Der Hauptvorteil der Verwendung der verknüpften async-Bibliothek besteht darin, dass * eine Anzahl gängiger Operationen in einem asynchronen Stil * umgebrochen/bereitgestellt wird. Während "einfache" [Promises] (http://wiki.commonjs.org/wiki/Promises/A) (dh jQuery.Deferred) verwendet werden kann, würde es viel mehr boilerplate (wenn eine dieser Operationen in einem gewünscht wird asynchronen Stil), da Sie Ihre eigenen Versionen dieser Funktionen schreiben müssten. Die verknüpften Async-Bibliotheken und Promises funktionieren auf die gleiche Weise - ein * Callback * wird verwendet. –

+3

Was ich an Versprechungen mag, ist, dass du etwas von einer Funktion zurückbringst und stattdessen einen Rückruf annimmst, den du später anrufen wirst (für mich ist es wie: Ich kann dir diesen Wert in diesem Moment nicht zurückgeben, aber ich verspreche dir das wird einen Wert erhalten). Was ich nicht mag ist, dass Sie 2 Funktionen bestehen müssen, aber das wird gelöst, wenn EcmaScript Harmony bereit ist. Angesichts der Tatsache, dass Task.js so großartig ist, sind Versprechen wirklich zukunftssicher. Vielleicht wird es interessant sein, ein Modul zu entwickeln, das die Lücke zwischen Versprechen und Rückrufen schließt (so etwas wie Async, aber ein Versprechen). –

Antwort

3

Da Sie Ihre Frage mit Knoten markiert haben, würde ich die Async-Bibliothek empfehlen. Die Kontrollflussfunktionen sind großartig, um mit den hässlichen und schwer zu verfolgenden Rückrufketten zu arbeiten und diese zu beseitigen. Die API ist sehr gut eingerichtet, um Callbacks, die der Signatur (error, result) des Knotens folgen, in die Steuerfunktionen einzufügen. Es ist grundsätzlich in fast allen Knoten-Skripten enthalten, die ich schreibe.

Sie können Async auch für die Clientseite verwenden, aber für die meisten Projekte ist das wahrscheinlich unnötig. jQuery enthält Versprechungen, und Sie können das gleiche mit ihnen erreichen.

1

Ich denke Versprechen/a und async Lib mit Unterschied Ziele, versprechen Fokus auf einem Schritt Async-Operation Fortschritt, und async Fokus auf Multi-Schritt-async betreiben, für Knoten, async hat eine wildere Verwendung für viele async apis.

durch die Art und Weise, wird der effektivste Weg, sehr häufig asynchroner Muster, einschließlich der Herstellung beliebige async Anrufe parallel

11

Die async Bibliothek kapselt ein paar sein mit asynchronen Operationen, die Verwendung benannte Funktion anstelle von Anonyme Funktionen beschäftigen und asynchron über eine Liste iterieren. Es wurde entwickelt, um mit "nodeback" (err, res) APIs zu arbeiten, was es für viele Node.js-Anwendungen nützlich macht. async ist jedoch eine spezifische Lösung, und es vereinfacht nur die asynchronen Muster in der Bibliothek enthalten.

Versprechen, im Gegensatz dazu sind meiner Meinung nach viel mehr allgemeine Lösung für das Problem des asynchronen Codes. Sie bieten nicht nur die offensichtlichen Vorteile auf den ersten Blick von fehleraufwirbelnden und abflachenden Callback-Pyramiden, Probleme, die sonst die Art von komplexen Mustern erfordern würden, können viel einfacher gelöst werden.

Ich werde dies mit einer kurzen Tour durch einige der verfügbaren Muster async demonstrieren. so etwas wie dies zum Beispiel wird die async.waterfall Funktion:

async.waterfall([ 
     function (cb) { 
     asyncCall('argument', cb); 
     }, 
     function(resultOfFirstCall, cb) { 
     anotherCall(resultOfFirstCall, 'someOtherArgument' cb); 
     }, 
    ], function(err, res) { 
     if (err) handle(err); 
     useFinalResult(res); 
    }); 

Es gibt kein Äquivalent zu async.waterfall in den meisten Versprechen Bibliotheken (oder zumindest es nicht einen in Q), weil es so einfach sie umzusetzen von Grund auf neu Array.reduce, wie so (zB auf Basis von Q aber so ziemlich das gleiche auf andere Versprechen Bibliotheken) mit:

[ 
    function() { 
    return asyncCall('argument'); 
    }, 
    function(resultOfFirstCall) { 
    return anotherCall(resultOfFirstCall, 'someOtherArgument'); 
    } 
].reduce(Q.when, Q()) 
.then(useFinalResult, handle); 

die anderen großen Funktionen in async umfassen async.parallel, die Q enthält als Q.all:

// async 
async.parallel([ 
    asyncFunc, 
    asyncFunc2 
    ], function(err, res) { 
     if (err) handle(err); 
     useFinalResult(res); 
     // res[0] === asyncFuncResult 
     // res[1] === asyncFunc2Result 
    }); 
// Q 
Q.all([ 
    asyncFunc(), 
    asyncFunc2() 
]).then(useFinalResult, handle); 

Und async.map.Sie tatsächlich brauchen nichtasync.map wenn Sie verspricht verwenden, weil die normale Array.map ausreichend ist:

// async 
async.map(['file', 'file2', 'file3'], fs.stat, function(err, res) { 
    if (err) handle(err); 
    useFinalResult(res); 
}); 
// Q 
Q.all(['file', 'file2', 'file3'] 
    .map(Q.nfbind(fs.stat))) 
    .then(useFinalResult, handle); 

Der Rest async ähnlich einfach ist prägnant zu implementieren, mit relativ einfachen Teile Ihrer Versprechen Bibliothek. (Beachten Sie, dass das letzte Beispiel eine Funktion verwendet Q.nfbind: nfbind und die anderen nf* Funktionen Q bietet im Grunde alles, was Sie Versprechen mit NodeBack-APIs verwenden müssen, so gibt es nicht einmal eine besonders große Impedanz versucht, Versprechen mit Bibliotheken, die NodeBacks erwarten verwenden .) Am Ende, ob Sie Versprechungen oder Nodebacks verwenden, liegt an Ihnen, aber ich denke, Versprechungen sind eine viel flexiblere, fähige und allgemein prägnante Möglichkeit, die meisten asynchronen Operationen zu implementieren.

Callbacks are imperative, promises are functional ist eine Lektüre für weitere Informationen in diesem allgemeinen Ader wert.

0

gumballhead empfohlen async.js, aber i würde empfehlen Parse Cloud Code verwenden, wenn Sie mit Knoten arbeiten. Ihre API hat Versprechen, zusammen mit anderen Goodies (wie eine Datenbank) eingebaut. Es spart Zeit und Sie müssen sich keine Gedanken über die Backend-Stabilität machen. Sie können jedes NPM-Modul mit einer kleinen Optimierung von module.exports in nur exports einfügen. Es fügt sich auch nahtlos in Ihr Frontend ein! Ich habe mit diesem Ansatz bei meinem aktuellen Projekt Erfolg gehabt und wollte nur einen neuen Ansatz kommentieren.

Fühlen Sie sich frei, mit irgendwelchen Gründen zu kommen, warum/wann Sie sollten nicht verwenden Cloud Code; denn ich habe noch keine solche Erfahrung gemacht.