异步 axios 不使用 NODEJS 运行承诺
Posted
技术标签:
【中文标题】异步 axios 不使用 NODEJS 运行承诺【英文标题】:Async axios dont run promise using 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 调用,但只有在返回对象之后
【参考方案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
);
【讨论】:
以上是关于异步 axios 不使用 NODEJS 运行承诺的主要内容,如果未能解决你的问题,请参考以下文章