【问题标题】:Async/await function yields on undefined异步/等待函数在未定义时产生
【发布时间】:2017-10-08 16:03:08
【问题描述】:

我在使用异步函数时遇到问题。我正在对 mongodb 进行查询(使用 mongoose),当我尝试取回信息时,它会产生未定义的信息。

这是我对数据库的查询(嵌套在函数中):

function kquery() {
  Krakentick.findOne(
    {
      iname: 'btcusd',
      n: { $lt: now }
    },
    'mk c n',
    function(err, tick) {
      if (err) {
        return console.log(err);
      } else {
        return tick;
      }
    }
  );
}

这是我的异步/等待函数:

async function compare() {
  var ktick = await kquery();
  console.log(ktick);
}

compare();

这些函数都在同一个文件中,当我运行它时,它会给我一个'undefined'。 而当我只是运行查询函数并提出console.log(tick) 而不是return tick 时,我得到了正确的信息:

{ _id: 59d1199cdbbcd32a151dcf21,
  mk: 'kraken',
  c: 430900,
  n: 1506875804217 }

我想,我在某处搞砸了回调,但我不确定在哪里或如何。 这是完整的文件:

const mongo = require('mongodb');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const server = mongoose.connect('mongodb://localhost/cryptoCollection', {
  useMongoClient: true
});

//Loading the mongoose schema:
const { Krakentick } = require('./kraken/model/krakenModel');
var now = Math.floor(new Date());

function kquery() {
  Krakentick.findOne(
    {
      iname: 'btcusd',
      n: { $lt: now }
    },
    'mk c n',
    function(err, tick) {
      if (err) {
        return console.log(err);
      } else {
        return tick;
      }
    }
  );
}


async function compare() {
  var ktick = await kquery();
  console.log(ktick);
}

compare();

提前感谢您的帮助!

【问题讨论】:

  • 我只读到 ",这是我的 async/await 函数:" 因为该函数确实返回 undefined.... Soooo....问题是什么?如果该函数应该返回一些东西,你应该让它返回一些东西。还是您的意思是日志输出而不是返回值?你不能等待kQuery 它也不会返回任何东西!没有承诺等待!您的 wait 语句“等待”立即返回 undefined 值。看起来你在`Krakentick.findOne 前面忘记了return?我希望该函数返回一个承诺,否则它不会有帮助。
  • 哦不,那些return 声明完全没用。你需要阅读承诺,最基本的......如果你没有承诺,你的async/await 是无用的,而你没有,因为似乎函数findOne 是基于回调的。您应该阅读一些有关 Javascript 中各种异步编程选项的信息。
  • 寻找“有希望的回调”或类似的东西,这很容易。示例:stackoverflow.com/a/41663320/544779
  • 这是一个不错的博客:2ality.com/2016/10/async-function-tips.html

标签: node.js mongodb asynchronous mongoose async-await


【解决方案1】:

您的kquery 函数必须返回承诺:

function kquery() {
  return Krakentick.findOne(
    {
      iname: 'btcusd',
      n: { $lt: now }
    },
    'mk c n',
    function(err, tick) {
      if (err) {
        return console.log(err);
      } else {
        return tick;
      }
    }
  );
}

【讨论】:

    【解决方案2】:

    只是贴出promesified kquery函数供参考:

    function kquery() {
      return new Promise((resolve, reject) => {
        Krakentick.findOne(
          {
            iname: 'btcusd',
            n: { $lt: now }
          },
          'mk c n',
          function(err, tick) {
            if (err) {
              reject(err);
            } else {
              resolve(tick);
            }
          }
        );
      });
    }
    

    接受的答案是上述答案,尽管 Mörre 之前在 cmets 中已经讨论和记录了它!我只是想把它留在那里以防它对某人有帮助!

    再次感谢您的宝贵帮助!

    【讨论】:

      猜你喜欢
      • 2018-05-27
      • 1970-01-01
      • 2020-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-17
      • 2019-08-07
      • 2023-03-13
      相关资源
      最近更新 更多