NodeJS 如何使用异步/等待回调[Javascript,Mongoose]

zy1mlcev  于 2022-11-22  发布在  Node.js
关注(0)|答案(1)|浏览(230)

我有3个异步函数:

ToDoItem.deleteMany({}); // deletes entire collection
ToDoItem.insertMany(itemArray); // adds new items to collection
ToDoItem.find({}); // finds all the items in the collection

这段代码本身并不能很好地工作,因为它们没有遵循一致的顺序。也就是说,插入可能发生在删除之前,这是我不希望的。
我可以用回调把它们链接在一起(callback hell),我也可以用.then把它们链接在一起,因为它们返回promises。
此外,可以为这些函数指定可选的回调,例如:

ToDoItem.find({}, (data) => { 
  console.log(data); 
});

这很有用,因为我想查看DB中与查询{}匹配的所有数据(即所有项)。
但是我不知道如何使用async和await来访问这些回调函数。我可以通过回调函数或.then来实现,但是代码更混乱。有没有办法做到这一点?
编辑:
根据Bergi的回复,我对代码进行了如下编辑:

async function setupDatabase() {
  const deleteResult = await ToDoItem.deleteMany({});
  console.log("Items deleted. Delete result:")
  console.log(deleteResult);

  const insertResult = await ToDoItem.insertMany(defaultItems);
  console.log("Items have been added successfully");
  console.log(insertResult);

  const findResult = await ToDoItem.find({});
  console.log("Here are the items:")
  console.log(findResult);
}

我的想法是否正确:

  1. deleteResult现在将被评估为删除确认(如果成功)或错误(如果被拒绝)。
    1.如果我想返回由.find({})找到的集合,我该怎么做,因为函数setupDatabase现在是异步的,并且返回一个promise。
    1.如果1)是正确的,我如何区分得到错误和得到结果的时间?
    根据康拉德的回复,我做了以下工作:
async function setupDatabase() {
  const deleteResult = await ToDoItem.deleteMany({});
  console.log("Items deleted. Delete result:")
  console.log(deleteResult);

  const insertResult = await ToDoItem.insertMany(defaultItems);
  console.log("Items have been added successfully");
  console.log(insertResult);

  const findResult = await ToDoItem.find({});
  console.log("Here are the items:")
  console.log(findResult);

  return findResult;
}

app.get("/", function(req, res) {
  (async function() {
    const objectList = await setupDatabase();
    let dataList = [];
    
    for (element of objectList) {
      dataList.push(element.todo);
    }
    res.render("list", {listTitle: "Today", newListItems: dataList});
  }());

我的想法是在setupDatabase函数中返回findResult,但这实际上是一个承诺,因为该函数是异步的,所以我将它 Package 在. get中的IIFE中。然后我迭代该列表并创建dataList,其中包含我想要呈现的实际数据。

ars1skjm

ars1skjm1#

回调时不要使用async/await
您使用带有promise的await,不应该将它们与回调混合使用--特别是,当您传递回调时,MongoDB不会返回promise。

await ToDoItem.deleteMany({}); // deletes entire collection
await ToDoItem.insertMany(itemArray); // adds new items to collection
const data = await ToDoItem.find({});

我认为[await表达式]现在的计算结果要么是删除确认(如果成功),要么是错误(如果被拒绝),对吗?
否。await的结果是成功履行承诺的值。如果拒绝承诺,则会将错误作为异常抛出,您可以handle it with a try / catch block
如果我想返回.find({})找到的集合,我该怎么做,因为函数setupDatabase现在是异步的,并且返回一个promise。
async/await语法不会改变任何东西。函数以前是异步的,并且it's impossible to immediately return the result,不管你使用回调或promise .then()链接语法还是await语法。返回一个promise实际上是可取的-调用者只需要等待它!

相关问题