【问题标题】:Async axios dont run promise using NODEJS异步 axios 不使用 NODEJS 运行承诺
【发布时间】:2018-06-09 23:46:31
【问题描述】:

我正在开发一个多人游戏,在客户端使用 vue 并使用 nojejs 作为游戏服务器(我使用vue-sockets.io 与客户端和服务器通信)。 当我在节点端创建游戏实例时,它将具有图块并隐藏(两个图像数组都来自 api)。对于这个使用axios,问题是创建的游戏在运行axios之前返回给客户端。所以客户端会得到没有图像的游戏。

createGame(playerName, socketID, boardSize) {
    this.contadorID = this.contadorID+1;

        var game = new MemoryGame(this.contadorID, playerName, boardSize);

        new Promise(function(resolve, reject) {
            console.log("a");
            game.getTiles().then(response=>{
                console.log("getTiles");
        game.tiles = game.getRandomNPieces(response.data.data, game.board.length/2);
                console.log(game.tiles);
      }).catch(function (error) {
        console.log(error);
      });
            console.log('=>' + game.tiles);
        }).then(function(result) { // (***)
            console.log("b");
          game.getHidden().then(response=>{
        game.hidden = game.getRandomHidden(response.data.data);
      }).catch(function (error) {
        console.log(error);
      });
        }).catch(function (error) {
            console.log(error);
        });
    game.player1SocketID = socketID;
    this.games.set(game.gameID, game);
    return game;
}

程序永远不会到达第二个 axios 调用。 gameList 日志来自返回给用户的游戏。

客户端 1 中的游戏实例(创建游戏的人):

客户端 2 中的游戏实例(游戏在大厅并且已经有图块):

【问题讨论】:

  • 为了有效地帮助您,您需要将代码的相关部分作为文本粘贴到问题中,并将它们格式化为代码。然后,我们可以复制/粘贴其中的一部分并进行更正。代码不应仅作为图像的外部链接提供。它应该作为文本粘贴到您的问题中。这些是堆栈溢出的规则/指南。您的代码有很多问题,但我不会手动从图像中重新键入您的所有代码,以便向您展示如何修复它。
  • @jfriend00 感谢您的建议!我将在这里传递我的代码!
  • 我不确定这段代码应该做什么,因为您有异步操作,但正在尝试同步返回尚未操作的game 对象,但第一个核心问题就是你创建了new Promise(),但你从不调用resolve()reject() 来解决或拒绝该承诺。你展示的是一个承诺反模式。无需将来自getTiles() 的现有承诺包装在另一个承诺中。您可以只使用它返回的承诺。这段代码有很多问题。不知道它的目标是什么。
  • @jfriend00 在此之前我只使用 axios,但这里的问题是:该方法将游戏实例返回给客户端,然后他运行 axios 代码。因此,客户端将获得没有图像的游戏。现在我尝试使用 resolve() 并且我的代码现在到达了两个 axios 调用,但只有在返回对象之后

标签: javascript node.js vue.js promise axios


【解决方案1】:

由于createGame() 似乎依赖一些异步操作来正确初始化游戏,因此您不能只从createGame() 同步返回已完成的游戏对象。正如您已经观察到的,createGame() 将在任何异步操作完成之前返回游戏对象。因此,相反,您需要返回一个 promise,其解析值为游戏对象,然后您需要将所有异步操作正确链接在一起,以便在游戏对象全部完成后解析您的主要 promise。这是一种结构方式:

createGame(playerName, socketID, boardSize) {
    this.contadorID = this.contadorID+1;

    var game = new MemoryGame(this.contadorID, playerName, boardSize);

    console.log("a");
    return game.getTiles().then(response=> {
        console.log("getTiles");
        game.tiles = game.getRandomNPieces(response.data.data, game.board.length/2);
        console.log(game.tiles);
        console.log('=>' + game.tiles);
        console.log("b");
        // return nested promise so it chains into main promise chain
        return game.getHidden().then(response=>{
            game.hidden = game.getRandomHidden(response.data.data);
        });
    }).then(() => {
        // finish initializing game object and 
        // make it be the resolved value of the returned promise
        game.player1SocketID = socketID;
        this.games.set(game.gameID, game);
        return game;
    }).catch(function (error) {
        // log error and rethrow so promise stays rejected
        // this will log for any of our rejected promises since they are chained
        console.log(error);
        throw error;
    });
}

而且,这会更改 createGame() 以返回一个承诺,因此您必须像这样更改使用它的方式:

someObj.createGame(...).then(game => {
    // game object is ready to use here
}).catch(err => {
    // error creating game object
});

【讨论】:

    猜你喜欢
    • 2018-11-03
    • 2019-06-21
    • 1970-01-01
    • 2014-01-04
    • 2018-08-26
    • 1970-01-01
    • 2019-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多