如何使用javascript中的间隔以顺序方式处理websocket响应

How to handle websocket responses in a sequential way using an interval in javascript?

本文关键字:方式 顺序 处理 websocket 响应 javascript 何使用      更新时间:2023-09-26

我正在写一款有单人和多人模式的纸牌游戏。在单人游戏的情况下,脚本会根据玩家的移动生成移动。我的问题是,这个脚本在眨眼之间就移动了,我想让玩家感觉到人工智能正在"思考"它的移动,因此等待每个响应,然后再显示2秒。

由于我使用的是带有javascript客户端的浏览器+服务器架构,因此这种等待相当有问题。我目前的代码没有按照我希望的方式运行。其想法是,当响应从websocket客户端到达并由ai生成时,响应会被推入队列。还有一个间隔,每2秒运行一次,并尝试从队列中弹出。这是我的代码:

        // interval
        var responseQueue = [];
        $interval(function () {
            var response = responseQueue.shift();
            if (response !== undefined) {
                processResponse(response);
            }
        }, OPPONENT_MOVE_REFRESH_INTERVAL);
        // websocket response
        SocketFactory.subscribe("/user/queue/game.gameResponse", function (response) {
            var res = JSON.parse(response.body);
            // the current player moved, refreshing view
            if ($scope.username === res.currentPlayerId) {
                processResponse(res);
            } else {
                // the opponent moved (the ai in this case)
                responseQueue.push(res);
            }
        });

我得到的是一些看似随机的行为。卡片会出现,但不是每隔2秒出现,有时数据会丢失。我做错了什么?

注意玩家可能会移动不止一次,所以有时我会快速连续移动2-3次AI。

类似以下内容应该会更好地工作,因为它确保了响应和屏幕操作之间的延迟,而不仅仅是基于上次计划的视图更新的延迟。我仍然不确定这是否能阻止你丢失的卡片(你的代码看起来确实不错),但它会使延迟更加一致。

 // interval
    var responseQueue = [];
    function next() {
        var response = responseQueue.shift();
        if (response !== undefined) {
            processResponse(response);
        }
        if(responseQueue.length) next.timer=setTimeout(next, 2000);
    }
    // websocket response
    SocketFactory.subscribe("/user/queue/game.gameResponse", function (response) {
        var res = JSON.parse(response.body);
        // the current player moved, refreshing view
        if ($scope.username === res.currentPlayerId) {
            processResponse(res);
        } else {
            // the opponent moved (the ai in this case)
            clearTimeout(next.timer);
            responseQueue.push(res);
            next.timer=setTimeout(next, 2000);
        }
    });

现在,什么都不会发生,直到2秒后的其他事情。