异步 axios 不 运行 承诺使用 NODEJS
Async axios dont run promise using NODEJS
我正在开发一款多人游戏,在客户端使用 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 中的游戏实例(游戏在大厅中并且已经有磁贴):
由于 createGame()
似乎依赖于一些异步操作来正确初始化游戏,因此您不能仅同步 return 来自 createGame()
的已完成游戏对象。正如您已经观察到的,createGame()
将在任何异步操作完成之前 return 游戏对象。因此,相反,您需要做的是 return 一个承诺,其解析值是游戏对象,然后您需要将所有异步操作正确地链接在一起,以便在游戏对象时解决您的主要承诺都完成了。这是一种构造方法:
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()
更改为 return 承诺,因此您必须像这样更改使用方式:
someObj.createGame(...).then(game => {
// game object is ready to use here
}).catch(err => {
// error creating game object
});
我正在开发一款多人游戏,在客户端使用 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 中的游戏实例(游戏在大厅中并且已经有磁贴):
由于 createGame()
似乎依赖于一些异步操作来正确初始化游戏,因此您不能仅同步 return 来自 createGame()
的已完成游戏对象。正如您已经观察到的,createGame()
将在任何异步操作完成之前 return 游戏对象。因此,相反,您需要做的是 return 一个承诺,其解析值是游戏对象,然后您需要将所有异步操作正确地链接在一起,以便在游戏对象时解决您的主要承诺都完成了。这是一种构造方法:
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()
更改为 return 承诺,因此您必须像这样更改使用方式:
someObj.createGame(...).then(game => {
// game object is ready to use here
}).catch(err => {
// error creating game object
});