【问题标题】:How to Use Async/Await With Callbacks [Javascript, Mongoose]如何使用 Async/Await 回调 [Javascript, Mongoose]
【发布时间】:2022-11-18 06:28:17
【问题描述】:

我有 3 个异步函数:

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

仅此代码并不能很好地工作,因为它们没有遵循一致的顺序。 IE。插入可能发生在删除之前,这是我不希望的。

我可以使用回调将它们链接在一起(回调地狱),我也可以使用 .then 将它们链接在一起,因为它们返回承诺。但是,我想使用异步/等待。

此外,可以为这些函数提供可选的回调,例如:

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

这很有用,因为我想查看我的数据库中与查询 {} 匹配的所有数据(即所有项目)。

但是我不知道如何使用异步和等待来访问这些回调。我可以通过回调或.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 现在将评估为删除确认(如果成功)或错误(如果被拒绝)。与 insertResult 和 findResult 类似吗?

  2. 如果我想返回 .find({}) 找到的集合,我该怎么办,因为函数 setupDatabase 现在是异步的并返回一个承诺。

  3. 如果 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。但这实际上是一个承诺,因为函数是异步的,所以我将它包装在 .get 中的 IIFE 中。然后,我遍历此列表并创建了 dataList,其中包含我要呈现的实际数据。

【问题讨论】:

  • deleteResult 现在将评估为删除确认(如果成功)或错误(如果被拒绝)- 不,会抛出错误,如果你想处理它们,你必须捕获它们
  • 如果我想返回 .find({}) 找到的集合怎么办- 你使用return 声明,在调用中你可以像往常一样处理承诺
  • 康拉德,感谢您的回复。我必须坐在第一个上。如果你能看一看,我在我的帖子中做了第二个编辑。我想我明白了(代码有效)我只是想验证您是否有任何注意事项或疑虑。谢谢你。

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


【解决方案1】:

您不要将 async/await 与回调一起使用。

您将 await 与承诺一起使用,并且您不应将它们与回调混合使用 - 特别是,当您传递回调时,MongoDB 不会返回承诺。你需要写

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

【讨论】:

  • 谢谢,这很有道理。我在我的帖子中创建了一个编辑以反映我更新的代码。如果您能够检查出来,我也在那里写了两个后续问题。感谢您花时间写这篇回复和回答!
猜你喜欢
  • 2019-07-20
  • 2018-02-28
  • 1970-01-01
  • 2018-09-05
  • 2019-04-15
  • 1970-01-01
  • 1970-01-01
  • 2023-01-05
  • 2017-10-21
相关资源
最近更新 更多