2014-05-22 13 views
8

Ho iniziato a utilizzare le promesse, uso Node.js Mango (con mangusta) e bluebird .. Il problema che sto avendo è per qualche motivo quando ordino la chiamata alla mangusta con le funzioni di ritorno promesse (sto assumendo questo è il modo corretto per tornare e catena) allora ottengo:JavaScript promette manuele e bluebird mancanti catch and fail

typeError: Object #<Promise> has no method 'fail' 

se cambio il non riescono a catturare tanto sono lo stesso problema:

typeError: Object #<Promise> has no method 'catch' 

quello che faccio è utilizzare la funzione (null, funzione) modello che è esattamente sicuro un e prendere. Tuttavia il fermo/fallire è più leggibile. Qualche idea sul perché sto ricevendo questo e come dovrei risolvere questo problema?

Ecco un esempio del blocco di codice.

User.findOne({ 'email' : user_email }).exec() 
}).then (promisedTransformUserSchemaToFrontendObjectWithProjectMapping) 
    .then (function (feUser) { 
     return new Promise(function (resolve, reject) { 
      res.json(feUser); 
      return resolve(feUser); 
     }); 
    }).fail/catch (function (err) { 
     console.log(err); 
     sendError(res,"failed to get user",err); 
    }); 

E qui è lo stacktrace:

TypeError: Object #<Promise> has no method 'catch' 
    at module.exports.app.put.User.update.email (app\controllers\router.js:165:16) 
    at callbacks (node_modules\express\lib\router\index.js:164:37) 
    at isLoggedIn (app\controllers\router.js:741:10) 
    at callbacks (node_modules\express\lib\router\index.js:164:37) 
    at param (node_modules\express\lib\router\index.js:138:11) 
    at param (node_modules\express\lib\router\index.js:135:11) 
    at pass (node_modules\express\lib\router\index.js:145:5) 
    at Router._dispatch (node_modules\express\lib\router\index.js:173:5) 
    at Object.router (node_modules\express\lib\router\index.js:33:10) 
    at next (node_modules\express\node_modules\connect\lib\proto.js:193:15) 
+0

puoi condividere la traccia dello stack? –

+2

Non utilizzare le promesse restituite da mangusta, solo promisifyAll e utilizzare esclusivamente i metodi '* Async' – Esailija

+0

Anche il bit' new Promise' soffre dell'anti-pattern posticipato – Esailija

risposta

15

mangusta 4.1+ manutentore suggerimento:

es2015 (ES6):

require('mongoose').Promise = Promise; 

bluebird:

require('mongoose').Promise = require('bluebird'); 

Q:

require('mongoose').Promise = require('q').Promise; 
+0

questo è sorprendente. grazie mille! – sabrehagen

+0

perché solo +3? usando require ('mangusta'). Promise = Promise; facilmente aggiunto supporto cattura e ha reso il mio mondo migliore. Molte grazie!! – Sulliwane

5

Non so moongose, ma in generale, funzioni come fallire o cattura sono scorciatoie di convenienza e non sono una parte delle promesse Spec. In quanto tale, la libreria non ha bisogno di renderle conformi alle promesse. Apparentemente nel tuo caso non ci sono.

È possibile ottenere stessa funzionalità con then(successHandler, rejectionHandler).

Al fine di gestire il rifiuto promessa, si può riscrivere il codice come segue:

User.findOne({ 'email' : user_email }).exec() 
}).then (promisedTransformUserSchemaToFrontendObjectWithProjectMapping) 
    .then (function (feUser) { 
     return new Promise(function (resolve, reject) { 
      res.json(feUser); 
      return resolve(feUser); 
     }); 
    }).then (undefined, function (err) { 
     console.log(err); 
     sendError(res,"failed to get user",err); 
    }); 
+0

sì, ho già scritto che è quello che sto facendo ora .... –

+0

Pensavo che il catch fosse almeno MDN ce l'aveva nei documenti insieme a Promise. tutti rifiutano e risolvono. –

0

Sembra che il problema stava mescolando i due tipi di promesse (Bluebird e Mongoose) ..

Una volta ho usato il promsifyAll sull'oggetto db, il pescato ha iniziato a lavorare ..

// promisify all model using mongoomise.. 
 
require('../../mongoomise').promisifyAll(mongoose, require('bluebird'))

+0

puoi postare codice di lavoro qui –

+0

@MuhammadUmer prova questo piccolo pezzo di codice che ho aggiunto, spero che sia d'aiuto. –

+0

Se si utilizza la mangusta 4.1.0 (rilasciata nel 2015-07-24) o superiore, non si dovrebbe usare 'promisify' con mangusta. La risposta di Jason Sebring dovrebbe essere preferita (la mia opinione è che la soluzione marcata debba essere cambiata). http://mongoosejs.com/docs/promises.html#plugging-in-your-own-promises-library – ippi

3

Un altro modo per farlo è indicato nella documentazione Bluebird:

https://github.com/petkaantonov/bluebird/blob/master/API.md#promiseresolvedynamic-value---promise

Puoi avvolgere la promessa mangusta in Promise.resolve di Bluebird(), e si otterrà indietro una promessa uccello azzurro.

Promise.resolve(User.findOne({ 'email' : user_email }).exec()) 
.then (promisedTransformUserSchemaToFrontendObjectWithProjectMapping) 
    .then (function (feUser) { 
      res.json(feUser); 
      return feUser; 
    }).fail/catch (function (err) { 
     console.log(err); 
     sendError(res,"failed to get user",err); 
    });