首页 > 解决方案 > 异步等待构建一个带有许多可选部分的猫鼬查询,然后是一个最终的 exec

问题描述

我有一些 javaScript 代码正在调用在猫鼬模式上定义的自定义 schema.static 函数,并且正在使用 async/await 进行调用...

// =====================================
//
// =====================================
const insertNewRecord = async (report) => {

  console.log('111');
  const filter = { identity: report.identity, role: report.role, active: true };

  // default filter of record (by priority) - admin view, top 1 record
  const found = await Tests.getRecords(filter, undefined, true, 1); 

  if (!found) {
    console.log('222 - NOT FOUND SO INSERT');

    try {
      inserted = await Tests.create(report);
      if (inserted) {
         console.log('333 - Record Inserted', report);
      }
    } catch (e) {
      console.log('444 - ERROR ON POST', e);
    }

    console.log('555');
  }

  console.log('666');
}

我如何调用在架构上定义的自定义“getRecords”方法(通过 schema.statics),该方法执行许多属性检查,然后在最终调用 exec() 执行很多,并得到一个结果。

它查找在模式文件中的子类上定义的各种静态功能的存在以及它们是否存在(并非所有模式都定义它们并且它们很少相同 - 即使获取记录的过程是。它传递查询允许更多选项链接或添加。

IE

// =====================================
// types of schema functionality present
// by schema.statics.<> in the schema...
// =====================================
schema.statics.poulateAdminList = query => {
  query
    .populate({
      path: 'configs',
      populate: {
        path: 'sensors',
        select: { _id: 1, ip: 1, ipv4: 1, plugin: 1, sensor: 1, auth: 1, timestamp: 1 },
      },
    })
    .populate({
      path: 'preferences',
    });
};

schema.statics.poulateList = query => {
  query
    .where({ active: true })
    .populate({
      path: 'configs',
      populate: {
        path: 'sensors',
        select: { _id: 1, ip: 1, ipv4: 1, plugin: 1, sensor: 1 },
      },
      select: { _id: 1, name: 1, active: 1 },
    })
    .populate({
      path: 'preferences',
      select: { _id: 1, theme: 1, tableColumns: 1 },
    })
    .select('identity email configs preferences role');
};

schema.statics.defaultSort = query => {
  query.sort({ priority: 1, identity: 1 });
};

这一切都chained来自BaseSchema每个猫鼬模式继承的getRecords。

// ============================================
// Defined in a base class that all schema have
// ============================================
async getRecords (where = {}, sort = null, admin = false, limit = 10) {
  const q = this.find(where);

  if (sort) {
    q.sort(sort);
  } else if (this.defaultSort) {
    this.defaultSort(q);
  }

  if (admin && this.poulateAdminList) {
    this.poulateAdminList(q);
  } else if (this.poulateList) {
    this.poulateListResponse(q);
  }

  // limit # of records
  q.limit(limit);

  // returns promise from q `find` but not exec() part ???
  return await q.exec();
},

当我称之为这个时,我得到的安慰是:

111
     <==== return too soon -looks like its the q but exec() not fired 
666
222 - NOT FOUND SO INSERT
333 - Record Inserted' { ... record stuff ... }
555

我知道它在 exec() / promise 附近 - 但我真的希望能够通过将数字查询元素链接在一起来构造一个查询,并且在从函数 getRecords 返回之前仍然等待答案

有谁知道如何实现这种链接并使用异步?

标签: javascriptinheritancemongooseasync-await

解决方案


您可以创建一个 Promise 并等待函数解析或使用回调函数返回数据。

例如你可以做这样的事情

    let a = Foo():
    a.then ( function onComplete (response) {
    //You can continue with your remaining functions here 
    }).catch ( function onError (error){
    console.log('Error', error);
    })

   Function Foo () {
     return new Promise ( function ( resolve, reject ) {
       Execute your query here.
     });
   }

至于回调函数,这里是一个例子

function asyncOperation ( a, b, c, callback ) {
  // ... lots of hard work ...
  if ( /* an error occurs */ ) {
    return callback(new Error("An error has occurred"));
  }
  // ... more work ...
  callback(null, d, e, f);
}

asyncOperation ( params.., function ( err, returnValues.. ) {
  //This code gets run after the async operation gets run
});

推荐阅读