2016-01-21 42 views
1

我在NodeJS中異步執行時遇到問題。特別是,我有很多用例,我希望在代碼中稍後使用異步請求的結果,並且不希望將整個事件包裝在另一個縮進級別中,例如async.parallel使用承諾將異步函數的結果作爲「變量」返回

據我所知,解決方案是使用承諾,但我努力獲得實施的權利,我試過的資源沒有幫助。

我目前的問題是這樣的: 我需要在插入MongoDB文檔時立即得到_id。我已經從使用MongoJS切換到使用官方的MongoDB驅動程序,因爲我知道MongoJS不支持承諾。任何人都可以通過提供一個基本的例子來說明如何使用promise來返回這個值嗎?

再次感謝。

回答

1

隨着Node.js的驅動程序,使用收集的insert()方法,它返回一個承諾。下面的例子說明了這一點:

var Db = require('mongodb').Db, 
    MongoClient = require('mongodb').MongoClient, 
    Server = require('mongodb').Server; 

var db = new Db('test', new Server('localhost', 27017)); 

// Fetch a collection to insert document into 
db.open(function(err, db) { 
    var collection = db.collection("post"); 

    // Create a function to return a promise 
    function getPostPromise(post){ 
     return collection.insert(post); 
    } 

    // Create post to insert 
    var post = { "title": "This is a test" }, 
     promise = getPostPromise(post); // Get the promise by calling the function 

    // Use the promise to log the _id 
    promise.then(function(posts){ 
     console.log("Post added with _id " + posts[0]._id);  
    }).error(function(error){ 
     console.log(error); 
    }).finally(function() { 
     db.close(); 
    }); 
}); 

您還可以使用貓鼬的save()方法,因爲它返回一個Promise。一個基本的例子來證明這一點如下:

// test.js 
var mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 

// Establish a connection 
mongoose.connect('mongodb://localhost/test', function(err) { 
    if (err) { console.log(err) } 
}); 

var postSchema = new Schema({ 
    "title": String 
}); 

mongoose.model('Post', postSchema); 

var Post = mongoose.model('Post'); 

function getPostPromise(postTitle){ 
    var p = new Post(); 
    p.title = postTitle; 
    return p.save(); 
} 

var promise = getPostPromise("This is a test"); 
promise.then(function(post){ 
    console.log("Post added with _id " + post._id); 
}).error(function(error){ 
    console.log(error); 
}); 

運行程序

$ node test.js 
Post added with _id 5696db8a049c1bb2ecaaa10f 
$ 
+1

第一個示例非常完美。謝謝! – Nodal

+1

@Nodal不用擔心,很樂意幫助:) – chridam

+0

嗨,在第一個例子中,我得到一個錯誤,說'TypeError:promise.then(...)。error不是一個函數。我一直無法找到有關此錯誤的更多信息,但我認爲它要麼是缺少使用承諾所需的模塊,要麼是Mongodb中的承諾實現不支持'.error'?或者當然完全是其他的東西。 – Nodal

1

那麼你可以使用Promise.then()的傳統方法,或者如果你可以使用ES6,請嘗試生成器函數(生成器直接包含在Node中,不需要運行時標誌)。通過這種方式,你可以簡單地編寫代碼:

//You can use yield only in generator functions 
function*() { 
    const newDocument = new Document({firstArg, SecondArg}); 
    const savedDocument = yield newDocument.save(); 
    //savedDocument contains the response from MongoDB 

}

你可以閱讀更多關於功能* here

+0

我確實能夠使用ES6。這看起來很有前途(沒有雙關語!)。我要去做這個鏡頭,回到你身邊,也許明天,因爲我沒有太多時間,無數的事情將不可避免地出問題。再次感謝! – Nodal

+1

好吧,現在我發現我忘記提及我的示例代碼取決於Mongoose,但它與純解相同=>簡單地產生Promise – yunicz