2014-05-22 77 views
8

我已經開始使用承諾,我使用Node.js芒果(與貓鼬)和藍鳥.. 我遇到的問題是由於某種原因,當我鏈接貓鼬調用與函數返回的承諾(我假設這是返回正確的方式和連鎖),然後我得到:JavaScript承諾貓鼬和藍鳥缺少捕獲和失敗

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

如果我改變趕不上然後我得到了同樣的問題:

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

我所做的就是使用函數(null,function)模式,它完全失敗了抓住。 但是,catch/fail更具可讀性。任何線索爲什麼我得到這個以及我應該如何解決這個問題?

這是一個代碼塊的例子。

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); 
    }); 

這裏是堆棧跟蹤:

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

你能分享堆棧跟蹤嗎? –

+2

不要使用貓鼬返回的承諾,只是promisifyAll和專門使用'*異步'方法 – Esailija

+0

此外'新的承諾'位遭受延遲反模式 – Esailija

回答

15

貓鼬4.1+維護者建議:

ES2015(ES6):

require('mongoose').Promise = Promise; 

藍鳥:

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

問:

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

這太神奇了。非常感謝! – sabrehagen

+0

爲什麼只有+3?使用require('mongoose')。Promise = Promise;輕鬆添加支持,讓我的世界變得更美好。非常感謝!! – Sulliwane

5

我不知道moongose,但在一般情況下,像失敗或捕捉功能方便快捷,並且不承諾規範的一部分。因此,圖書館不需要讓他們遵守承諾。顯然在你的情況下,他們不在那裏。

您可以使用then(successHandler, rejectionHandler)實現相同的功能。

爲了處理承諾拒絕,你可以按照如下重寫代碼:

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

是的,我已經寫過,這是我現在正在做的事情...... –

+0

我認爲抓住是至少MDN有它在文件與Promise一起。都拒絕並解決。 –

0

看來,這個問題是混合的兩種類型的承諾(藍鳥和貓鼬)..

一旦我用了promsifyAll數據庫對象,漁獲開始工作..

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

+0

你可以在這裏發佈工作代碼 –

+0

@MuhammadUmer試試我添加的這一小段代碼,我希望它有幫助。 –

+0

如果你使用貓鼬4.1.0(2015-07-24發佈)或以上,那麼你不應該用貓鼬使用'promisify'。賈森塞布林的答案應該是首選的(我認爲應該改變標記的解決方案)。 http://mongoosejs.com/docs/promises.html#plugging-in-your-own-promises-library – ippi

3

另一種方式來做到這一點顯示在藍鳥文檔:

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

你可以用貓鼬承諾在藍鳥的Promise.resolve(),你會得到一個藍鳥承諾。

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); 
    });