Promettendo manualmente pg.connect con Bluebird

Voglio pg.connect metodo pg.connect di node-postgres insieme al metodo inner connection.query fornito nel callback.

Posso .promisify , ma ho bisogno di implementare il primo manualmente (se mi manca qualcosa qui, per favore spiega).

Il fatto è che non sono sicuro che questo codice sia corretto o debba essere migliorato? Il codice funziona, voglio solo sapere se sto usando Bluebird come previsto.

 // aliases var asPromise = Promise.promisify; // save reference to original method var connect = pg.connect.bind(pg); // promisify method pg.connect = function (data) { var deferred = Promise.defer(); connect(data, function promisify(err, connection, release) { if (err) return deferred.reject(err); // promisify query factory connection.query = asPromise(connection.query, connection); // resolve promised connection deferred.resolve([connection,release]); }); return deferred.promise; }; 

Getta via tutto quel codice di callback orribile, quindi fallo da qualche parte nell’inizializzazione dell’applicazione:

 var pg = require("pg"); var Promise = require("bluebird"); Object.keys(pg).forEach(function(key) { var Class = pg[key]; if (typeof Class === "function") { Promise.promisifyAll(Class.prototype); Promise.promisifyAll(Class); } }) Promise.promisifyAll(pg); 

Più tardi in qualsiasi luogo è ansible utilizzare il modulo pg come se fosse stato progettato per utilizzare le promesse per iniziare:

 // Later // Don't even need to require bluebird here var pg = require("pg"); // Note how it's the pg API but with *Async suffix pg.connectAsync(...).spread(function(connection, release) { return connection.queryAsync("...") .then(function(result) { console.log("rows", result.rows); }) .finally(function() { // Creating a superfluous anonymous function cos I am // unsure of your JS skill level release(); }); }); 

Ormai ci sono un certo numero di librerie che fanno questo per te:

  • pg-promise – Promises generiche / A + per PG
  • Postgres-Bluebird
  • DBH-ph
  • pg-bluebird

Aggiornamento per bluebird 3 :

La pg.connectAsync(...).spread(function(connection, release) { ... }) non funzionerà più, perché l’API di bluebird è cambiata: http://bluebirdjs.com/docs/new- in-bluebird-3.html # promisification-api-changes .

Il problema è che promisifyAll in bluebird 3 non gestisce più argomenti per impostazione predefinita. Ciò comporta la chiamata .spread() che riporta un .spread() TypeError simile al seguente:

 TypeError: expecting an array or an iterable object but got [object Null] 

Per risolvere questo problema, è ansible abilitare esplicitamente più argomenti per connect / connectAsync . Fai quanto segue dopo tutte le cose promettenti di cui sopra:

 ... pg.connectAsync = Promise.promisify(pg.connect, { multiArgs: true }); 

Suggerisco di modificare la soluzione di Petka Antonov un po ‘

 var Promise = require('bluebird'); var pg = require('pg'); Object.keys(pg).forEach(function (key) { var Cls = null; try { Cls = pg[key]; if (typeof Cls === 'function') { Promise.promisifyAll(Cls.prototype); Promise.promisifyAll(Cls); } } catch (e) { console.log(e); } }); Promise.promisifyAll(pg); 

qui 'pg[key] racchiuso nel blocco try-catch perché pg[key] può retrunfare error quando si tenta di accedere a pg['native']