Mongoose Promise 的异步性

Posted

技术标签:

【中文标题】Mongoose Promise 的异步性【英文标题】:Asynchronicity of a Mongoose Promise 【发布时间】:2018-05-01 10:34:59 【问题描述】:

首先,请原谅我有点模棱两可的标题;我找不到更合适的:

场景

我正在使用 Mongoose 获取一些数据,然后使用 ejs 渲染它们。为了便于说明,请考虑以下几点:

// Schema
var UserSchema = mongoose.Schema(
  Username: String,
  City: String
)
// Model
var User = mongoose.model('User', UserSchema);

来自我的服务器文件:

app.get('/view', function (req, res) 
  // What I am trying to do            
  User.find().exec().then(vals=>
            res.send(vals)
        )

问题

上述代码按预期工作,但对于其他文件可访问的代码以及使升级更容易,我想将其移动到另一个文件,然后 require() 该文件。

handler.js

// Promise: Get All Names
function FetchData()
    return User
    .find()
    .exec();


module.exports = 
    Get: function()
        val = User.find().exec()
        .then(vals=>
            // Expected to return only after the above is complete
            return vals
        )
    


然后,从我的服务器文件中:

var handler = require('handler')

app.get('/view', function (req, res) 
  res.send(handler.Get())
);

很遗憾,此代码无法按预期工作

我的想法

我改变了参数并调整了代码几次,但无法弄清楚出了什么问题。 似乎 Get() 的值甚至在承诺被消耗之前就被返回了(这令人费解)。

非常欢迎任何帮助:)

【问题讨论】:

你仍然不能在 promise 回调的外部函数中 return。您需要返回 promise 对象本身,并在调用者处使用 then 使用其结果。 Promise 不会使您的代码同步,它们不会使未来的值立即可用! 有解决办法吗? 没有。在您发明时间机器之前,没有任何解决方法。 【参考方案1】:

我觉得你应该是这样的:

module.exports = 
  Get: function() 
    return User.find().exec()
      .then(vals => 
        // Expected to return only after the above is complete
        return vals
      )
  

然后

app.get('/view', function (req, res) 
  handler.Get().then((response) => 
    res.send(response);
  );
);

所以,从Get 返回承诺,然后使用它的then API。

【讨论】:

建议的代码不起作用:TypeError: Cannot read property 'then' of undefined 错误表示您没有将return 添加到Get。还要检查更新的代码。 问题依旧:/ 你会想要drop the pointless .then(vals => vals)【参考方案2】:

这里的代码可以帮助你。

把你的主服务器文件改成这样的

app.get('/view', function (req, res) 
  handler.Get().then(vals => 
       res.send(vals);
  );

在 handler.js 文件中,你可以这样做

module.exports.Get = function()
     return new Promise((resolve, reject) => 
          User.find().exec(function(err, users)
               if(!err)
                    resolve(users);
               
          );     
     );

【讨论】:

以上是关于Mongoose Promise 的异步性的主要内容,如果未能解决你的问题,请参考以下文章

猫鼬承诺错误

Mongoose与bluebird结合使用实例

[js高手之路]Node.js+jade+express+mongodb+mongoose+promise实现todolist

异步函数不等待Promise

then 语句中的异步 Mongoose 回调

浅谈promise对象