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

如何让代码等待forEach循环执行完成后再返回数据?

问题描述

以下是我的getUsers函数:

const getUsers = async (req, res) => {
    try {
        ddb.get({
            TableName: "Tablename",
            Key: { Username: req.query.username }
        },(err,user) => {
            if(err || Object.keys(user).length === 0) {
                return res.status(404).json("Something went wrong")
            } else {
                const userSociety = Object.keys(user.Item.Societies)[0]
                ddb.get({
                    TableName: "Tablename",
                    Key: { SocietyCode: userSociety }
                },(err, society) => {
                    if(err || Object.keys(society).length === 0) {
                        return res.status(400).json({ message: "Could not fetch society members" })
                    } else {
                        const users = Object.keys(society.Item.SocietyMembers)
                        const usersData = []
                         users.forEach(async u => {
                            ddb.get({
                                TableName: "TestMyMohallaUsers",
                                Key: { Username: u }
                            },async (err,user) => {
                                if(err || Object.keys(user).length === 0) {
                                } else usersData.push({
                                    Username: user.Item.Username,
                                    Firstname: user.Item.Name
                                })
                            })
                        })
                        return res.status(200).json({ message: "Data detched successfully", Users: usersData })
                    }
                })
            }
        })
    } catch (error) {
        return res.status(500).json({ error: "Internal Server Error" })
    }
}

我希望等待forEach循环执行完成后,再通过return语句返回数据,但目前return语句返回的usersData是空数组。显然我的代码没有等待forEach执行完毕就返回了,请问该如何解决?(补充:ddb是DynamoDB的实例)

解决方法

核心问题

  1. forEach不支持异步等待:你在forEach里用了async回调,但forEach不会等待异步操作完成,会直接执行后续代码,导致返回时usersData还没被填充。
  2. 回调嵌套+异步混用:当前用的是DynamoDB的回调式API,嵌套层级深,还混合async/await,时序控制混乱。

具体解决方案

步骤1:改用DynamoDB的Promise式API

AWS SDK的DynamoDB方法可以通过.promise()转换为Promise,配合async/await处理异步,避免回调地狱,更易控制时序。

步骤2:用Promise.all替代forEach处理批量异步

对于批量异步任务,用map生成异步任务数组,再通过Promise.all等待所有任务完成,确保数据全部填充后再返回。

修改后的完整代码

const getUsers = async (req, res) => {
    try {
        // 获取当前用户信息(改用Promise+await)
        const userResult = await ddb.get({
            TableName: "Tablename",
            Key: { Username: req.query.username }
        }).promise();

        if (!userResult.Item) {
            return res.status(404).json("Something went wrong");
        }

        // 获取用户所属社团信息
        const userSociety = Object.keys(userResult.Item.Societies)[0];
        const societyResult = await ddb.get({
            TableName: "Tablename",
            Key: { SocietyCode: userSociety }
        }).promise();

        if (!societyResult.Item) {
            return res.status(400).json({ message: "Could not fetch society members" });
        }

        // 提取社团成员用户名列表
        const memberUsernames = Object.keys(societyResult.Item.SocietyMembers);

        // 批量生成获取成员信息的异步任务
        const memberPromises = memberUsernames.map(async username => {
            try {
                const memberResult = await ddb.get({
                    TableName: "TestMyMohallaUsers",
                    Key: { Username: username }
                }).promise();
                // 仅返回有效用户数据
                if (memberResult.Item) {
                    return {
                        Username: memberResult.Item.Username,
                        Firstname: memberResult.Item.Name
                    };
                }
                return null;
            } catch (err) {
                // 单个成员获取失败时返回null,不影响整体
                return null;
            }
        });

        // 等待所有异步任务完成,过滤掉无效数据
        const usersData = (await Promise.all(memberPromises)).filter(item => item !== null);

        // 返回填充完成的结果
        return res.status(200).json({ message: "Data fetched successfully", Users: usersData });

    } catch (error) {
        return res.status(500).json({ error: "Internal Server Error" });
    }
}

关键改进点

  • 全程用async/await替代回调,代码层级清晰,异步时序可控。
  • 用map+Promise.all确保所有成员数据获取完成后再返回响应。
  • 优化空值判断逻辑(!userResult.Item),更符合DynamoDB返回规范。
  • 单个成员获取失败时返回null,最后过滤无效数据,避免影响整体结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 08:30:51