异步axios不使用NODEJS运行承诺

时间:2017-12-29 14:39:40

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

我在客户端使用 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;
}

Print with logs

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

客户端1中的游戏实例(创建游戏的人): Game instance in client 1 (who created the game)

客户端2中的游戏实例(游戏在大厅,已有瓷砖): Game instance in client 2 (the game is in lobby and already have the tiles)

1 个答案:

答案 0 :(得分:1)

由于createGame()似乎依赖于某些异步操作来正确初始化游戏,因此您不能仅从createGame()同步返回已完成的游戏对象。正如您已经观察到的那样,createGame()将在任何异步操作完成之前返回游戏对象。所以,相反,你需要做的是你需要返回一个其解析后的值是游戏对象的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
});