async / await不适用于mongo数据库查询

时间:2019-01-04 05:57:36

标签: javascript node.js mongodb promise async-await

工作案例:

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

不起作用的情况:

异步等待不适用于mongo数据库查询

尝试then(),异步/等待

我有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 db查询时):

当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])
    });
  });

2 个答案:

答案 0 :(得分:3)

快速澄清:

  1. .collection('name')返回一个Collection实例,而不是Promise,因此不需要await
  2. toArray()有两种模式:一种是在提供函数时使用回调,要么在没有提供回调函数时返回Promise。

由于toArray的双重操作模式,在提供回调函数的同时,您实际上期望从toArray()中获得Promise结果,从而导致undefined,因为回调优先级高,并且没有返回承诺()。

此外,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);
       }
    });
  });
}

答案 1 :(得分:0)

注意:首先,我真的要感谢@mihai Potra的最佳答案。

我们在这里

情况1:

如mihai所述,如果它是一个需要查找文档并从MongoDb返回的函数,则下面的答案非常酷

const db = <get db somehow>;
async function functionOne(email) {
  const collection = db.collection('allinonestore');
  return collection.find({"email": email}).toArray();
}

情况2:

据我所知,如果有嵌套函数每次都需要在ans以下返回值,那将是最好的

-不需要为每个功能使用async / await关键字,或者无需then()

function one(<parameter>) {
return new Promise(function(resolve, reject) {
const collection = connection.get().collection('<collection_name>');
const docs = collection.find({"Key": Value_fromFunction}).toArray( function (err, result) {
resolve(result[0]);
});

就是这样,在需要时使用resolve回调。