You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript(Mongoose)中结合Async/Await与回调函数

异步数据库操作的async/await用法问题

问题背景

我有3个异步函数:

ToDoItem.deleteMany({}); // 清空整个集合
ToDoItem.insertMany(itemArray); // 向集合添加新条目
ToDoItem.find({}); // 查询集合中所有条目

单独执行这些代码效果不好,因为它们的执行顺序不固定。比如插入操作可能在删除操作之前执行,这不符合预期。

我可以用回调函数链式调用(但会陷入回调地狱),也可以用.then链式调用——因为这些函数会返回Promise。不过我更倾向于使用async/await。

另外,这些函数支持传入可选的回调函数,比如:

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

这个特性很实用,因为我想查看数据库中匹配查询条件{}的所有数据(也就是全部条目)。但我不知道怎么通过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);
}

我有几个疑问:

  • deleteResult的值要么是删除成功的确认信息,要么是失败时的错误信息?insertResult和findResult也是如此吗?
  • 如果我想返回.find({})查询到的集合,但setupDatabase是async函数会返回Promise,该怎么做?
  • 如果第一点正确,我该怎么区分返回的是错误还是正常结果?

第二次修改与思路

根据Konrad的回复,我做了如下修改:

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,但因为该函数是async函数,返回的是Promise,所以我在.get方法里用立即执行函数表达式(IIFE)包裹代码。之后遍历这个集合,创建包含需要渲染的实际数据的dataList。

内容的提问来源于stack exchange,提问作者713sean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 00:30:45