2016-01-21 45 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