【问题标题】:node.js: how to return a value of a callback function?node.js:如何返回回调函数的值?
【发布时间】:2016-11-15 19:36:28
【问题描述】:

我有以下代码(不能按预期工作):

var express = require('express')
var app = express()
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/interviews';

app.get('/', function(req, res){
    var result = get_document(res);
    res.send( result // show the results of get document in the browser //)
    console.log("end");
});

app.listen(3000, function(req, res) {
    console.log("Listening on port 3000");
});

function get_document() {
  MongoClient.connect(url, function(err, db) {
    var col = db.collection('myinterviews');
    var data = col.find().toArray(function(err, docs) {
      db.close();
      return docs[0].name.toString(); // returns to the function that calls the callback
    });
  });
}

函数“get_document”应该返回存储在“myinterviews”集合中的文档。问题是'return docs [0] ...'行返回到col.find(这是调用回调的函数)而不是app.get(...)中的变量'result'。

你知道如何让文档返回'result'变量吗?

【问题讨论】:

    标签: node.js callback


    【解决方案1】:

    你应该看看promise api。

    “get_document”函数应该返回一个新的承诺,带有解决和拒绝函数回调(成功/失败)。

    所以,它应该看起来有点像这样:

    var express = require('express')
    var app = express()
    var MongoClient = require('mongodb').MongoClient;
    var url = 'mongodb://localhost:27017/interviews';
    
    app.get('/', function(req, res){
    var result = get_document(res).then(function (doc) {
      res.send( doc);
    });
     // show the results of get document in the browser //)
    console.log("end");
    });
    
    app.listen(3000, function(req, res) {
        console.log("Listening on port 3000");
    });
    
    function get_document() {
    
      return new Promise(
    
         function (resolve, reject)
           MongoClient.connect(url, function(err, db) {
           var col = db.collection('myinterviews');
           var data = col.find().toArray(function(err, docs) {
            db.close();
            resolve(docs[0].name.toString()); // returns to the function that calls the callback
        });
      });
      );
    }
    

    【讨论】:

    • 很好的答案。谢谢。至于承诺 - 你不认为 bluebird.promisify (bluebirdjs.com/docs/api/promise.promisify.html) 更好吗?
    • 是的,它可能是。但是我没有使用它,所以我不能根据经验发表评论:)。看看这个:softwareengineering.stackexchange.com/questions/278778/…
    【解决方案2】:

    您的get_document 函数异步运行。对MongoClient.connect() 的调用可能需要一些时间,因此无法立即返回。要从数据库调用中返回您所追求的值,您必须将回调传递给 get_document 函数。所以它应该看起来像这样:

    var express = require('express')
    var app = express()
    var MongoClient = require('mongodb').MongoClient;
    var url = 'mongodb://localhost:27017/interviews';
    
    app.get('/', function(req, res){
        var result = get_document(function(result) {
            res.send(result);
            console.log("end");
        });
    });
    
    app.listen(3000, function(req, res) {
        console.log("Listening on port 3000");
    });
    
    function get_document(done) {
      MongoClient.connect(url, function(err, db) {
        var col = db.collection('myinterviews');
        var data = col.find().toArray(function(err, docs) {
          db.close();
          done(docs[0].name.toString()); // returns to the function that calls the callback
        });
      });
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 1970-01-01
    • 2015-07-16
    • 1970-01-01
    • 2014-06-13
    • 1970-01-01
    相关资源
    最近更新 更多