javascript - async/await 不适用于 mongoDB 查询

标签 javascript node.js mongodb promise async-await

工作案例:

当我们调用一个异步函数并且该函数返回一个 promise resolve() 时,async await 工作正常

不工作的情况:

async await 不适用于 mongo DB 查询

试过 then()、async/await

我有 2 个 JS 文件。

在 one.js 文件中,我正在导入 functionone.js 中的函数

工作案例:

当one.js的样子

var functiononestatus = transactions.functionone(req.session.email).then((came) => {
  console.log(came); // getting `need to be done at first` message
  console.log("exec next")
});

当functionone.js看起来像

module.exports.functionone = functionone;

async function functionone(email) {
  return await new Promise((resolve, reject) => {
    resolve('need to be done at first')
  });
});

不工作的情况(当需要执行 mongo 数据库查询时):

当one.js的样子

var functiononestatus = transactions.functionone(req.session.email).then((came) => {
  console.log(came); // getting undefined
  console.log("exec next")
});

当functionone.js看起来像

module.exports.functionone = functionone;

async function functionone(email) {

  //mongo starts
  var collection = await connection.get().collection('allinonestores');
  await collection.find({
    "email": email
  }).toArray(async function(err, wallcheck) {
    return await new Promise((resolve, reject) => {
      resolve(wallcheck[0])
    });
  });

最佳答案

快速说明:

  1. .collection('name')返回 Collection instance,不是 Promise,所以不需要 await
  2. toArray()以两种模式运行:要么在提供函数时使用回调,要么在未提供回调函数时返回 Promise。

您实际上是在期待 toArray() 的 Promise 结果同时提供回调函数,导致 undefined ,因为toArray()的双重操作模式导致callback优先,不返回promise。

此外,toArray(callback)不需要 async用作回调。

检索集合的代码应该如下所示:

const client = await MongoClient.connect('your mongodb url');
const db = client.db('your database name'); // No await here, because it returns a Db instance.
const collection = db.collection('allinonestores'); // No await here, because it returns a Collection instance.

然后是获取结果的代码:

const db = <get db somehow>;

// You could even ditch the "async" keyword here,
// because you do not do/need any awaits inside the function.
// toArray() without a callback function argument already returns a promise.
async function functionOne(email) {

  // Returns a Collection instance, not a Promise, so no need for await.
  const collection = db.collection('allinonestore');

  // Without a callback, toArray() returns a Promise.
  // Because our functionOne is an "async" function, you do not need "await" for the return value.
  return collection.find({"email": email}).toArray();
}

和代码替代,使用回调:

const db = <get db somehow>;

// You could even ditch the "async" keyword here,
// because you do not do/need any awaits inside the function.
// You're forced to return a new Promise, in order to wrap the callback
// handling inside it
async function functionOne(email) {

  // Returns a Collection instance, not a Promise, so no need for await.
  const collection = db.collection('allinonestore');

  // We need to create the promise outside the callback here.
  return new Promise((resolve, reject) => {
    db.find({"email": email}).toArray(function toArrayCallback(err, documents) {
       if (!err) {
         // No error occurred, so we can solve the promise now.
         resolve(documents);
       } else {
         // Failed to execute the find query OR fetching results as array someway failed.
         // Reject the promise.
         reject(err);
       }
    });
  });
}

关于javascript - async/await 不适用于 mongoDB 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54033722/

相关文章:

javascript - 用javascript控制TAB的顺序( react )

javascript - jquery - 需要一个比 .change 更好的事件来触发验证逻辑

javascript - 使用前未定义的前向引用任务

node.js - Cassandra 客户端不会插入

javascript - Socket.io 使用 mongoDB 文档发出 [object Object]

django - Mongoengine 原始 find_and_modify 查询给出 "Must either update or remove"异常

javascript - 在 SVG 线性渐变停止偏移中绑定(bind) Angular2 值?

javascript - 在父 DIV 的鼠标移出时隐藏子元素 - AngularJs

mysql - 如何将mysql数据渲染到jade文件?

javascript - 如何将字符串转换为对象?