Comprensione delle promesse in node.js

Da quello che ho capito ci sono tre modi per chiamare il codice asincrono:

  1. Eventi: es. request.on("event", callback);
  2. Callback: es. fs.open(path, flags, mode, callback);
  3. promesse

Ho trovato una libreria di promise https://github.com/kriszyp/node-promise ma non capisco.

Qualcuno potrebbe spiegare quali sono le promesse e perché dovrei usarlo?

Inoltre, perché è stato rimosso da Node.js?

Promises in node.js ha promesso di fare un po ‘di lavoro e quindi ha avuto callback separati che sarebbero stati eseguiti per il successo e l’insuccesso, oltre a gestire i timeout. Un altro modo di pensare alle promesse in node.js era che erano emettitori che potevano emettere solo due eventi: successo ed errore.

La cosa bella delle promesse è che puoi combinarle in catene di dipendenze (fai Promise C solo quando Promise A e Promise B sono complete).

Rimuovendoli dal core node.js, ha creato la possibilità di creare moduli con diverse implementazioni di promesse che possono stare al di sopra del nucleo. Alcuni di questi sono la promise del nodo e il futuro .

Dal momento che questa domanda ha ancora molti punti di vista (come la mia) volevo sottolineare che:

  1. node-promise mi sembra piuttosto morto (l’ultimo commit era circa 1 anno fa) e non contiene quasi nessun test.
  2. Il modulo dei future sembra molto gonfio per me ed è mal documentato (e penso che le convenzioni sui nomi siano solo sbagliate)
  3. Il modo migliore per andare sembra essere il framework q , che è sia attivo che ben documentato.

Una promise è una “cosa” che rappresenta, per così dire, i risultati “finali” di un’operazione. Il punto da notare qui è che, astrae i dettagli di quando qualcosa accade e ti permette di concentrarti su cosa dovrebbe succedere dopo che qualcosa accade. Ciò si tradurrà in un codice pulito e gestibile in cui invece di avere una richiamata all’interno di un callback all’interno di un callback, il tuo codice sarà simile al seguente:

  var request = new Promise(function(resolve, reject) { //do an ajax call here. or a database request or whatever. //depending on its results, either call resolve(value) or reject(error) //where value is the thing which the operation's successful execution returns and //error is the thing which the operation's failure returns. }); request.then(function successHandler(result) { //do something with the result }, function failureHandler(error) { //handle }); 

Le specifiche delle promesse affermano che è una promise

 then 

il metodo dovrebbe restituire una nuova promise che si è adempiuta quando il callback riuscitoHandler o failHandler è terminato. Ciò significa che è ansible concatenare le promesse quando si dispone di una serie di attività asincrone che devono essere eseguite e si assicura che la sequenza delle operazioni sia garantita proprio come se si fossero utilizzati i callback. Quindi, invece di passare una richiamata all’interno di un callback all’interno di un callback, il codice con promesse concatenate ha il seguente aspetto:

 var doStuff = firstAsyncFunction(url) { return new Promise(function(resolve, reject) { $.ajax({ url: url, success: function(data) { resolve(data); }, error: function(err) { reject(err); } }); }; doStuff .then(secondAsyncFunction) //returns a promise .then(thirdAsyncFunction); //returns a promise 

Per saperne di più sulle promesse e perché sono super cool, controlla il blog di Domenic: http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/

Questo nuovo tutorial su Promises dell’autore di PouchDB è probabilmente il migliore che abbia mai visto. Saggiamente copre i classici errori del debuttante mostrando i corretti schemi di utilizzo e anche alcuni anti-pattern che sono ancora comunemente usati – anche in altri tutorial !!

Godere!

PS Non ho risposto ad altre parti di questa domanda perché sono state ben coperte dagli altri.

Mike Taulty ha una serie di video , ognuno dei quali meno di dieci minuti, che descrive come funziona la libreria Promessa WinJS.

Questi video sono piuttosto istruttivi e Mike riesce a mostrare la potenza dell’API Promise con alcuni esempi di codice ben scelti.

 var twitterUrl = "http://search.twitter.com/search.json?q=windows"; var promise = WinJS.xhr({ url: twitterUrl }); promise = promise.then( function (xhr) { }, function (xhr) { // handle error }); 

Il trattamento di come vengono gestite le eccezioni è particolarmente buono.

Nonostante i riferimenti a WinJs, questa è una serie di video di interesse generale, poiché l’API Promise è ampiamente simile nelle sue numerose implementazioni.

RSVP è un’implementazione Promise leggera che supera la suite di test Promise / A +. Mi piace molto l’API, perché è simile nello stile all’interfaccia WinJS.

Aggiornamento aprile 2014

Per inciso, la libreria WinJS è ora open source .

Un altro vantaggio delle promesse è che la gestione degli errori e il lancio e l’intercettazione delle eccezioni è molto meglio che tentare di gestirli con i callback.

La libreria bluebird implementa le promesse e offre grandi tracce di stack lunghe, è molto veloce e avvisa sugli errori non rilevati. Inoltre è più veloce e utilizza meno memoria rispetto alle altre librerie di promise, secondo http://bluebirdjs.com/docs/benchmarks.html

Cos’è esattamente una promise?

Una promise è semplicemente un object che rappresenta il risultato di un’operazione asincrona. Una promise può essere in uno dei seguenti 3 stati:

in attesa : questo è lo stato iniziale, significa che la promise non è né soddisfatta né respinta.

compiuto :: Ciò significa che la promise è stata soddisfatta, significa che il valore rappresentato dalla promise è pronto per essere utilizzato.

respinto :: Ciò significa che le operazioni falliscono e quindi non possono soddisfare la promise. Oltre agli stati, ci sono tre quadro importanti associate a promesse che dobbiamo davvero capire

  1. funzione executor :: funzione executor definisce l’operazione asincrona che deve essere eseguita e il cui risultato è rappresentato dalla promise. Inizia l’esecuzione non appena l’object promise viene inizializzato.

  2. resolve :: resolve è un parametro passato alla funzione executor e, nel caso in cui l’executor venga eseguito correttamente, questa risoluzione viene chiamata passando il risultato.

  3. reject :: reject è un altro parametro passato alla funzione executor e viene utilizzato quando la funzione executor non riesce. Il motivo dell’insuccesso può essere passato allo scarto.

Quindi, ogni volta che creiamo un object promise, dobbiamo fornire Executor, Resolve e Reject.

Riferimento :: Promesse

Recentemente ho anche esaminato le promesse in node.js. Ad oggi il file when.js sembra essere la via da percorrere per via della sua velocità e dell’uso delle risorse, ma la documentazione su q.js mi ha dato una comprensione molto migliore. Quindi usa when.js ma i documenti q.js per capire l’argomento.

Dal readme q.js su github:

Se una funzione non può restituire un valore o lanciare un’eccezione senza bloccare, può invece restituire una promise. Una promise è un object che rappresenta il valore di ritorno o l’eccezione generata che la funzione potrebbe eventualmente fornire. Una promise può anche essere utilizzata come proxy per un object remoto per superare la latenza.