【问题标题】:How to fix [object Promise] in a async function?如何在异步函数中修复 [object Promise]?
【发布时间】:2019-04-05 20:25:43
【问题描述】:

我想在 NodeJS 的 Mongo 数据库中获取插入文档的 _id。

首先我调用插入文档的函数

// First Function
router.post('/add', function(req, res) {
  var db = req.db;
    var collection = db.get('entrys');

    var id = databaseAPI.createRecord(req, req.body.name);
    console.log("Finished " + id)
});

我将下面第二个函数的返回值保存在 id 中,但是当我记录它时,我得到 [object Promise]

插入到不同 .js 文件中的函数:

//Second Function
createRecord: async function(req, name) {
      var db = req.db;
      var collection = db.get('entrys');
      var objectToInsert = {
        Name: name
      };

      collection.insert(objectToInsert, function(err){
   if (err) {
     return null;
    console.log("err");
  }
   // Object inserted successfully.
        console.log(objectToInsert._id) // This returns the ID 
     return objectToInsert._id; // This should return the ID to the first function but I get [object Promise]

我尝试与asyncawait 一起玩,就像这个问题Promise is returning [object Promise] 的第一个答案一样,但如果我这样做,我会得到“未定义”而不是“[object Promise]”。

我对 JavaScript 还很陌生。也许有人可以指出我正确的方向。

编辑:

如果我这样做var id = await databaseAPI.createRecord(req, req.body.name)

我得到“SyntaxError: await is only valid in async function”

现在,如果我使函数异步,当我 console.log id 时,我会得到“未定义”。

【问题讨论】:

  • 你的第二个函数不完整。但是通过查看它,它看起来就像您正在使用的库,使用回调而不是承诺。由于您在回调中返回值,因此它不会作为承诺返回。

标签: javascript node.js mongodb


【解决方案1】:

试试这个:

// First Function
router.post('/add', async function(req, res) {
  var db = req.db;
    var collection = db.get('entrys');

    var id = await databaseAPI.createRecord(req, req.body.name);
    console.log("Finished " + id)
});

基本上,您需要在开头使用await 调用.createRecord。为了比工作,你需要使 post handler async 因为 await 只能在 async 函数中使用。

【讨论】:

  • 感谢您的回答,但我已经尝试过了。看看我的编辑
  • 返回undefined,说明createRecord的逻辑有问题。尝试反转错误处理逻辑以在 console.log 之后返回 null 以查看发生了什么 - 现在 console.log 永远不会被调用。更好的是,您可以自己抛出错误并在调用函数时尝试捕获它。另外,使用 createRecord = async function() 而不是 createRecord: async function,如果这是在顶层而不是在对象内部定义的。
【解决方案2】:

首先,您应该将第一个函数改写成这样(如@MrfksIV 所建议的那样),但带有一个 Try-catch 块,这样您就可以看到错误:

router.post('/add', async function(req, res) {
  var db = req.db;
  var collection = db.get('entrys');

  try {
    var id = await databaseAPI.createRecord(req, req.body.name);
    console.log("Finished " + id)
  } catch(e) {
    console.log("Err: " + err);
  }
});

关于第二个函数,您在该函数中没有返回任何内容,这就是您未定义的原因。而且,在回调中,您期望objectToInsert 将被collection.insert 方法修改,这不太可能。可能此方法会将插入的对象传递给回调。 所以,我想你应该重写你的第二个函数来处理回调,像这样:

//Second Function
createRecord: function(req, name) {
  var db = req.db;
  var collection = db.get('entrys');
  var objectToInsert = {
    Name: name
  };

  return new Promise(function(resolve, reject) {
    collection.insert(objectToInsert, function(err, insertedObj){
      if (err) {
        console.log("err");
        reject(err)
      } else {
        console.log(insertedObj);
        resolve(insertedObj._id);
      }
    });
  });
}

mongoose callbacks 遵循function(err, data) 的模式。

【讨论】:

  • 使用此代码,我得到一个 errUnhandledPromiseRejectionWarning: #UnhandledPromiseRejectionWarning: Unhandled PromiseRejectionWarning: Unhandled Promise Rejection 。这可能是一个愚蠢的问题,但是对于库,您是指模块吗?如果是,我使用猫鼬。
  • 谢谢,我改一下答案。
  • @RjuJBong 更正了答案,它现在应该可以工作了。其他问题,记得添加你正在使用的模块和版本,让试图帮助你的人检查文档并给你更好的答案。
猜你喜欢
  • 2019-10-23
  • 2021-08-01
  • 2020-01-22
  • 2021-02-15
  • 2017-05-18
  • 2017-03-19
  • 1970-01-01
  • 2017-10-29
  • 2020-08-13
相关资源
最近更新 更多