2015-04-12 6 views
13

In una promessa libreria bluebird ha funzione promisifyAll o altre librerie simili che pretendono di convertire funzioni asincrone con pattern di callback in promesse basate cioè. resolve(), reject() o done() .. Come funziona?Come promisifyAll funziona, o quali sono i requisiti per farlo funzionare?

Ad esempio:

function myAsync1 (data, url, callBack) {...} 

e se l'ho messo in

Promise.promisify(myAsycn1); 

allora sarà il mio lavoro funzione come questa ..

myAsync1('{..}', 'http://..').then(function(){...}); 

Questo è stato mi dà fastidio. Esiste uno schema che le librerie o le funzioni asincrone non promettenti devono seguire per Bluebird promisifyAll per convertirle in metodi basati su promesse o c'è qualche magia che li converte.

Se poi quali sono i requisiti e come funziona con le librerie esistenti come mongodb ecc

+0

Si noti che la funzione non è "convertita", le funzioni sono immutabili. Invece, 'Promise.promisify' restituisce una * nuova * funzione che chiamerà il vecchio con il callback. – Bergi

+1

possibile duplicato di [Cercando di capire come funziona la promessa con BlueBird] (http://stackoverflow.com/q/26391419/1048572) – Bergi

+0

@Bergu potrebbe essere un duplicato, ma il suo titolo è scritto così male in termini di SEO che dopo la ricerca per quattro ore non l'ho incontrato una volta da remoto, infatti è più sul lato dell'esca per clic. –

risposta

20

C'è un modello che asincrone librerie non promettere o funzione devono seguire per Bluebird promisifyAll per convertirli in promesse metodi basati

Sì, c'è un motivo. Le funzioni che converte devono aspettarsi un callback come ultimo argomento. Inoltre, deve passare un errore come primo argomento del callback (null se nessun errore) e il valore restituito come secondo argomento.

La funzione BlueBird promisify è molto difficile da seguire a causa di ottimizzazioni, quindi vi mostrerò un modo semplice potrebbe essere scritta:

function promisify(fn) { 
    return function() { 
    var that = this; // save context 
    var args = slice.call(arguments); // turn into real array 
    return new Promise(function(resolve, reject) { 
     var callback = function(err, ret) { // here we assume the arguments to 
              // the callback follow node.js 
              // conventions 
     if(err != undefined) { 
      reject(err); 
     } else { 
      resolve(ret); 
     } 
     }; 
     fn.apply(that, args.concat([callback])); // Now assume that the last argument will 
               // be used as a callback 
    }); 
    }; 
} 

Ora potremmo implementare promisifyAll dai loop le funzioni nel bersaglio oggetto e utilizzando promisify su ciascuno di essi.

+0

quindi se questa convenzione allora significa asyncjs non segue la convenzione? https://gist.github.com/techsin/18a6b6d36ed0205a443a In questo si vede che le funzioni funzionano se solo il callback è il primo argomento. Questo comportamento è unico per asyncjs? –

+0

Per promesse ... la regola è che la funzione dovrebbe ricevere la callback come ultimo parametro e deve invocare quella richiamata con err come primo parametro, giusto? .. comunque, da parte loro vedo esempi come 'Promise.promisify ('request'); Promise.promisify ('FS'); Promise.promisify ('mangusta'); 'ecc. Tutti quei moduli/librerie, per una coincidenza, seguono questi requisiti. –

+1

@MuhammadUmer Questo è un esempio molto fuorviante di utilizzo della lib 'async'. Le funzioni passate a 'async.series 'dovrebbero prendere solo un singolo argomento, il callback. Quelle funzioni non avranno mai un argomento 'err'. –

2

Il metodo promisifyAll() promisifies l'intero modulo o oggetto che viene chiamato come parametro. Ciò significa che una copia di ciascuna proprietà dell'oggetto viene creata con il suffisso Async, che in realtà è una versione promessa dello stesso metodo, cioè è possibile utilizzare i metodi .then() o .done() su di esso.

Ad esempio, se si dispone di un metodo doSomething() nel modulo someModule, dopo aver chiamato Promise.promisifyAll(someModule) un nuovo metodo verrà creato nel modulo chiamato doSomethingAsync(). Si può usare in questo modo:

var someModule = require('some-module'); 
Promise.promisifyAll(someModule); 
someModule.doSomethingAsync().then(function(result) { 
    // do whatever you want with result, this function runs after doSomthingAsync() 
    // is finished and the returned value is stored in 'result' variable. 
}); 

Scopri i bluebird API documentation per ulteriori informazioni.

+0

so quale sia il risultato finale ma quello che voglio sapere è esattamente come? Le promesse si basano su chiamate interne e in qualche modo trasmettono l'errore in modo da poter eseguire '.catch' ... quindi DOSOmething() non mostra nulla di tutto ciò. –