2016-08-09 42 views
1

我理解JavaScript中的承諾或至少我認爲我確實(糾正我,如果我是錯誤的)。在Mongoose路徑中使用Promise

創建一個承諾:

var promise = new Promise(function(resolve, reject){ 
    // do something async here 

    if(itWorked){ 

    resolve(); 

    }else { 

    reject(); 
    } 

}); 

使用承諾:

promise.then(function(result){ 

},function(err){ 

}); 

我有一個基於MEAN堆棧和我的一些貓鼬路線的應用程序正在成爲一個回調地獄。我想擺脫貓鼬路線中的回調,並使用Promises處理它們。但我似乎無法弄清楚究竟該如何做到這一點。

例如:

app.get('/users', function(req, res){ 

    User.findOne(_id, function(err, user){ 
     if(err) 
     console.log(err) 
     else if(user){ 

     Receipt.findOne(user.bookName, function(err, book){ 
      if(err) 
      console.log(err) 

      else if(book){ 
      // again do something here 
      } 
     }) 
    } 
    }) 
}); 

在上面的例子中,你可以看到,代碼越來越難以閱讀和維護。我如何在這裏使用Promises來改進我的代碼?

回答

3

好的,首先你使用mongoose對不對?

User是你的貓鼬模型這是爲了響應方法,如findOne(query)findOneAndUpdate(query, update, opts)等。

調用任何這些方法後,調用,它返回查詢的方法exec()

查詢並不完全是一個Promise,您需要指定Mongo將使用哪些Promises。在這裏,我會建議使用原生的人的話,在你的項目中加入這一行:

const mongoose = require('mongoose') 
mongoose.Promise = Promise 

現在,這一指令返回你的承諾,真好!

User.findOne(q).exec() 

現在,您可以創建你的邏輯鏈條的承諾,例如:

return User 
    .findOne(_id) 
    .exec() 
    .then((user) => { 
     return Receipt 
     .findOne({ bookName: user.bookName }) 
     .exec() 
     }) 
    .then((receipt) => { 
      // example 
      return res.status(200).json(receipt) 
     })) 
    }) 

提示:我建議,以使代碼更清潔的創建輔助方法:

/** @return {Promise} */ 
function findUser(id) { 
    return User.findOne(id).exec() 
} 

/** @return {Promise} */ 
function findReceipt(bookName) { 
    return Receipt.findOne({ bookName }).exec() 
} 

// example 
function f(req, res) { 
    const userId = req.get('id') 

    return findUser(userId) 
    .then((user) => findReceipt(user.bookName)) 
    .then((receipt) => res.status(200).json(receipt)) 
    .catch((err) => res.status(500).json(null)) 
} 

// register your handler 
app.get('/book', f) 
+0

非常感謝你的回答。我有幾個問題來清除一些概念。在'mongoose.Promise = Promise'這一行中插入原生ES6承諾庫到貓鼬?當_findUser承諾返回時,'then'函數會運行嗎?我猜測術語'返回一個promise'意味着'_findUser'函數是否有'已解析'或'已拒絕'。我對嗎? – Skywalker

+0

準確地說,'mongoose.Promise = Promise'告訴貓鼬使用原生ES6承諾;當你解決'user'時,你可以開始一個新的任務(你注意到了返回嗎?)_findReceipt()_findReceipt()是一個很重要的任務, '。這也是一項繁重的任務,將返回一個「收據」。 **當**你已經解決'收據'時,你已準備好回覆你的回覆。如果** ANY **這些任務產生錯誤,您將執行您的'catch'語句 – Manu

+0

非常感謝您的解釋。我現在主要了解它。出於某種原因,我發現我的頭腦很難承諾。 – Skywalker