【问题标题】:How to properly async the MongoDB .save() with mongoose?如何正确地将 MongoDB .save() 与猫鼬异步?
【发布时间】:2023-01-20 03:44:27
【问题描述】:

我正在尝试在 MongoDB 数据库中使用 mongoose 插入多个文档,但在尝试同步两个中间件时遇到了一些问题。让我解释一下流程:

  1. 传递了一个文档数组 [A],我需要将它们全部插入到集合 [A] 中
  2. [A] 中的每个文档在插入时必须在另一个集合 [B] 中创建多个文档 [B](从一到三个)
  3. 每个 [B] 文档都必须更新另一个集合 [C] 中文档 [C] 中的信息。
  4. 完成所有这些任务后,我可以继续处理第二个 [A] 文档,等等...

    在我的代码中,我使用 [A] 文档上的一个 .pre“保存”中间件和 [B] 文档上的一个 .pre“保存”中间件来构建它。

    我尝试使用“.insertMany()”,但我也需要在单个文档 .save() 上运行这些中间件。

    下面是循环遍历数组 [A] 的所有文档的代码,称为“数据”,并将文档保存在其集合中:

    data.forEach(async (transaction) => {
        const document = new Transaction({
            date: transaction.date,
            amount: transaction.amount,
            type: transaction.type,
        });
        await document.save();
    });
    

    我使用 await 是因为我想在继续第二个文档之前等待这个文档的保存。因此,使用 .pre“保存”中间件,我可以在继续第二个 [A] 文档之前创建 [B] 文档。

    TransactionSchema.pre("save", async function (next) {
        const allTransactions = this.model("AllTransactions");
        var amount = Math.abs(this.amount);
    
        switch (this.type) {
            case "A":
                const A_Transaction = new allTransactions({
                    transaction_id: this._id,
                    amount: amount,
                    date: this.date,
                    type: "A",
                });
                await A_Transaction.save();
                break;
                
                case "B":
                    // ...
                    break;
    
                case "C":
                    // ...
                    break;
        }
        next();
    });
    

    使用相同的逻辑,我使用 await .save() 创建 [B] 文档(在本例中只有一个文档),因此我可以在 .pre save() 上使用第二个中间件来更新第三个集合中的文档。

    AllTransactionsSchema.pre("save", function (next) {
        const Data = this.model("Data");
        const DataToUpdate = Data.findById(//data id);
    
        DataToUpdate.then(async (instance) => {
            instance.values.forEach(async (value) => {
                //operations
                await instance.save();
            });
        });
        next();
    });
    
    

    问题是,[A] 数组的第二个文档是在所有中间件执行结束之前插入的。 我对所有 .save() 使用了 async await,但它好像不起作用。

    我试图弄清楚如何一个一个地同步所有这些操作;我仍然是 MongoDB 和 noSQL 的学生。

    谢谢!

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    用普通循环替换 forEach。当 await 被放置在 JavaScript 的高阶数组函数中时,它们实际上并不等待,相反它们只是触发多个异步调用。

    编辑:

    添加了一个示例

    const fireTransactions = async () => {
        for (const transaction of data) {
            const document = new Transaction({
                date: transaction.date,
                amount: transaction.amount,
                type: transaction.type,
            });
            await document.save();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-01
      • 2021-05-11
      • 1970-01-01
      • 2017-03-08
      • 2019-10-12
      • 2018-08-30
      • 2015-10-23
      • 1970-01-01
      • 2017-03-28
      相关资源
      最近更新 更多