【问题标题】:Using promises to return the result of an asynchronous function as a 'variable'使用 Promise 将异步函数的结果作为“变量”返回
【发布时间】:2016-04-27 10:30:01
【问题描述】:

我在 NodeJS 中的异步执行时遇到问题。特别是,我有很多用例,我想在我的代码中稍后使用异步请求的结果,并且不想将整个内容包装在另一个缩进级别中,例如async.parallel

我知道解决此问题的方法是使用 Promise,但我正在努力正确实施,而且我尝试过的资源没有帮助。

我目前的问题是: 我需要在插入 MongoDB 文档时立即获取它的_id。我已经从使用 MongoJS 切换到使用官方 MongoDB 驱动程序,因为我知道 MongoJS 不支持 Promise。任何人都可以通过提供如何使用承诺返回此值的基本示例来提供帮助吗?

再次感谢。

【问题讨论】:

    标签: javascript node.js mongodb asynchronous express


    【解决方案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

    【讨论】:

    • 我确实可以使用 ES6。这看起来很有希望(没有双关语!)。我要去试一试,然后回复你,也许明天因为我没有太多时间,无数的事情不可避免地会出错。再次感谢!
    • 好的,现在我看到我忘了提到我的示例代码依赖于 Mongoose,但它几乎与纯解决方案相同 => 只需产生 Promise
    【解决方案2】:

    使用 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();
        }); 
    });
    

    您还可以使用 Mongoose 的 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
    $
    

    【讨论】:

    • 第一个例子绝对完美。谢谢!
    • @Nodal 不用担心,很乐意提供帮助 :)
    • 嗨,在第一个示例中,我收到错误消息 TypeError: promise.then(...).error is not a function。我无法找到有关此错误的太多信息,但我认为要么是我缺少使用 Promise 所需的模块,要么是 Mongodb 中的 Promise 实现不支持.error?或者完全是别的东西。
    • 我目前可以与.catchposts.ops[0]._id 一起正常工作,但我当然想更全面地理解它:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 2017-10-16
    • 1970-01-01
    • 2022-12-22
    • 1970-01-01
    • 1970-01-01
    • 2018-04-13
    相关资源
    最近更新 更多