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

Node.js 如何在异步递归函数全部执行完成后运行后续逻辑

核心问题原因

你现在的代码存在两个导致无法等待递归全部完成的问题:

  • 调用__recoveryRecursive时没有加await,主控制器不会等待递归执行完成,就会直接走后续逻辑返回响应
  • 递归内部的update类异步方法、递归调用自身的逻辑都没有加await,导致异步操作状态无法被追踪,会游离在主流程之外

修复方案

给所有异步操作补充await关键字即可,修改后的完整代码如下:

const recoveryCategory = async (req, res) => {
    try {
        const categoryId = req.params.categoryId
        const category = await nmCategorySvcV2.getByIdDeleted(categoryId)

        if (category === null){
            throw new Error("This category is not deleted.")
        }

        // 加await等待递归完全执行完毕
        await __recoveryRecursive(categoryId)
        // 此处即可放置递归结束后需要执行的逻辑


        res.json({ success: true, message: "Success." })
    } catch (err){
        res.json({ success: false, message: err.message })
    }
}

const __recoveryRecursive = async (categoryId) => {
    const category = await nmCategorySvcV2.getByIdDeleted(categoryId)
    if (category === null){
        return
    }

    await nmCategorySvcV2.update(categoryId, { deleted: false })

    const categoryItens = await categoryItemSvcV2.getAllItensByCategory(categoryId)

    for (let i = 0; i < categoryItens.length; i++) {
        const categoryItem = categoryItens[i]

        if (categoryItem.deleted == true) {
            const item = await itemSvcV2.getByIdNoPopulate(categoryItem.item, categoryItem.page)

            if (item.deleted == true) {
                // 补充await追踪异步操作完成状态
                await itemSvcV2.update(item._id, { deleted: false })
                await categoryItemSvcV2.updateItensProp(item._id, { deleted: false })
            }

            const itemPrice = await itemPriceSvcV2.getById(categoryItem.price)

            if (itemPrice.deleted == true) {
                // 补充await追踪异步操作完成状态
                await itemPriceSvcV2.updateObject({ _id: itemPrice._id }, { deleted: false })
            }

            // 补充await追踪异步操作完成状态
            await categoryItemSvcV2.update(categoryItem._id, { deleted: false })

            if (categoryItem.next_steps.length > 0){
                for (let j = 0; j < categoryItem.next_steps.length; j++){
                    const categryNextStep = categoryItem.next_steps[j].category
                    // 递归调用补充await,等待子分类递归逻辑全部完成
                    await __recoveryRecursive(categryNextStep)
                }
            }
        }
    }
}

可选优化

如果业务允许子分类并行恢复,不需要按顺序执行,可以把next_steps的循环部分改成Promise.all提升执行效率:

if (categoryItem.next_steps.length > 0){
    const recoveryPromises = categoryItem.next_steps.map(item => __recoveryRecursive(item.category))
    await Promise.all(recoveryPromises)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 00:06:04