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

如何让Steam Bot的friendRelationship回调等待sendUpdate1完成后调用sendUpdate2

解决Steam Bot中sendUpdate1与sendUpdate2的顺序执行问题

我正在开发基于JavaScript的Steam Bot,当前代码如下:

const steam = new SteamUser(); // from steam-user library

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function steamAddFriend(user_steam_id) {
    // 3 attempts
    for (let i = 0; i < 3; i++) {
        try {
            await steam.addFriend(user_steam_id);
            console.log('Friend request is sent');
            // everything is ok
        } catch (err) {
            if (err.eresult === SteamUser.EResult.DuplicateName) {
                if (steam.myFriends[user_steam_id] === SteamUser.EFriendRelationship.Friend) {
                    console.log('This user is already in the friends list');
                } else if (steam.myFriends[user_steam_id] === SteamUser.EFriendRelationship.RequestInitiator) {
                    console.log('The friend request has already been sent earlier');
                }
                // non-critical error, but there is no point to continue trying
            } else if ((err.eresult === SteamUser.EResult.ServiceUnavailable || err.message === 'Request timed out') && i < 2) {
                // problem with Steam servers, wait 10 seconds and try again
                await sleep(10000);
                continue;
            } else {
                // critical error. for example, user_steam_id is invalid
                // sendNotification is fetch based function to send notification to me
                await sendNotification();
            }
        }
        break; // break the loop if there is no need to continue trying
    }
    try {
        // fetch based function to send updates to backend
        await sendUpdate1(user_steam_id);
    } catch (err) {
        // handle error
    }
}

// fired when relationship with user is changed (for example, a user accepted a friend request)
steam.on('friendRelationship', async (sid, relationship) => {
    if (relationship === SteamUser.EFriendRelationship.Friend) {
        const user_steam_id = sid.getSteamID64();
        console.log('User is added to friends');
        // here I need to wait until sendUpdate1 resolves
        // sendUpdate2 is fetch based function to send updates to backend
        await sendUpdate2(user_steam_id);
    }
});

steamAddFriend('71111111111111111');

需求

当friendRelationship回调触发(比如用户接受好友请求)时,必须等待steamAddFriend函数中的sendUpdate1 Promise解析完成后,再调用sendUpdate2,同时要保证机器人能同时处理多个用户。


实现方案

核心思路是用一个Map对象来存储每个用户对应的sendUpdate1 Promise,这样无论friendRelationship回调何时触发,都能找到并等待该用户的sendUpdate1完成后再执行sendUpdate2。具体修改如下:

  1. 新增全局Map跟踪每个用户的sendUpdate1任务:
// 存储每个用户的sendUpdate1 Promise,键为steamID64,值为Promise
const pendingSendUpdate1 = new Map();
  1. 修改steamAddFriend函数,将sendUpdate1的Promise存入Map,并在完成后清理:
async function steamAddFriend(user_steam_id) {
    // 3 attempts
    for (let i = 0; i < 3; i++) {
        try {
            await steam.addFriend(user_steam_id);
            console.log('Friend request is sent');
        } catch (err) {
            if (err.eresult === SteamUser.EResult.DuplicateName) {
                if (steam.myFriends[user_steam_id] === SteamUser.EFriendRelationship.Friend) {
                    console.log('This user is already in the friends list');
                } else if (steam.myFriends[user_steam_id] === SteamUser.EFriendRelationship.RequestInitiator) {
                    console.log('The friend request has already been sent earlier');
                }
                break; // non-critical error, stop trying
            } else if ((err.eresult === SteamUser.EResult.ServiceUnavailable || err.message === 'Request timed out') && i < 2) {
                await sleep(10000);
                continue;
            } else {
                await sendNotification();
                break;
            }
        }
        break;
    }

    // 创建sendUpdate1的Promise并存入Map
    const updatePromise = (async () => {
        try {
            await sendUpdate1(user_steam_id);
        } catch (err) {
            // 保留原错误处理逻辑
            console.error(`sendUpdate1 failed for ${user_steam_id}:`, err);
        }
    })();

    pendingSendUpdate1.set(user_steam_id, updatePromise);
    
    // 完成后从Map中移除,避免内存泄漏
    await updatePromise;
    pendingSendUpdate1.delete(user_steam_id);
}
  1. 修改friendRelationship回调,先等待对应用户的sendUpdate1完成:
steam.on('friendRelationship', async (sid, relationship) => {
    if (relationship === SteamUser.EFriendRelationship.Friend) {
        const user_steam_id = sid.getSteamID64();
        console.log('User is added to friends');

        // 等待该用户的sendUpdate1完成(如果存在)
        const updatePromise = pendingSendUpdate1.get(user_steam_id);
        if (updatePromise) {
            await updatePromise;
        }

        // 现在执行sendUpdate2
        await sendUpdate2(user_steam_id);
    }
});

方案说明

  • 多用户支持:Map的键是用户的steamID64,每个用户对应独立的Promise,完全隔离不同用户的处理流程,不会互相干扰。
  • 顺序保证:无论friendRelationship回调在sendUpdate1执行前还是执行中触发,都会等待sendUpdate1完成后再执行sendUpdate2。
  • 内存管理:sendUpdate1完成后会从Map中移除对应的Promise,避免长期占用内存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:52:47