gpt4 book ai didi

javascript - Promise 返回值不正确

转载 作者:行者123 更新时间:2023-12-01 02:26:38 25 4
gpt4 key购买 nike

我试图让一个函数返回一个 id 是否为 validId。然而,事实证明,有时,即使 await isValidId(230)truevalidId 也不是 230。

我认为这是因为 promise 总是异步解决的。是对的吗?那我该如何设计这个功能呢?

let validId = 230;
let isValidId = function(id){
return new Promise(resolve => {
//async code
resolve(validId === id);
});
}

if (await isValidId(230)){
//validId is not necessary 230
}

这是一个更完整的示例。

let playerAskedToLogOut = false;
let playersOnline = ['MyUsername'];
let canPlayerUseItem = async function(player,itemId){
let hasItem = await Database.playerHasItem(player, itemId);
let isStillOnline = playersOnline.includes(player);
playerAskedToLogOut = true; //normally called by another function
return hasItem && isStillOnline;
};

setInterval(() => {
useItems();
logOutPlayers();
}, 100);

let useItems = async function(){
if (await canPlayerUseItem('MyUsername', 'hammer')){
//the player is not online anymore. Yet, await canPlayerUseItem returned true
}
}
let logOutPlayers = function(){
if(playerAskedToLogOut)
playersOnline = []
}

最佳答案

问题中的代码存在语法错误:它在非async 函数中使用 await,但该函数不起作用。 (您已再次编辑代码以使 canPlayerUseItem async)

首先:在 async 函数中使用 new Promise 根本没有任何意义。该函数会自动为您创建一个 promise 。因此,代码(截至撰写本文时,您不断更改它)实际上应该是:

let canPlayerUseItem = async function(player,itemId){
let hasItem = await Database.playerHasItem(player, itemId);
let isStillOnline = playersOnline.includes(player);
return hasItem && isStillOnline;
};

canPlayerUseItem 的 promise 将以 true 解决的唯一原因是 hasItem 返回 true 并且 playersOnline > 包含 player 当我们进行检查时,这是之后我们等待playerHasItem..如果玩家在以下时间不在线您调用 canPlayerUserItem在线,当 playerHasItem 检查完成时,它将解析为 true

如果您想在等待 playerHasItem 调用之前进行 playersOnline 检查:

let canPlayerUseItem = async function(player,itemId){
if (playersOnline.includes(player)) {
return false;
}
return await Database.playerHasItem(player, itemId);
};

或者,如果您想检查两者(但它们可能已离线,然后在中间重新上线):

let canPlayerUseItem = async function(player,itemId){
if (playersOnline.includes(player)) {
return false;
}
let hasItem = await Database.playerHasItem(player, itemId);
let isStillOnline = playersOnline.includes(player);
return hasItem && isStillOnline;
};
<小时/>

在您最新的编辑中,您建议在 promise 解决方案之后将玩家从在线阵列中删除。这表明您在询问如何在代码中使用canPlayerUseItem知道玩家仍然在线。

答案:不能。您在 canPlayerUseItem 中执行的任何操作都无法保护您免受以下固有的竞争条件的影响:

if (await canPlayerUseItem(player, itemId)) {
// They player may now be offline
}

...因为玩家可能会在 canPlayerUseItem 完成检查之后但在使用该结果的代码运行之前退出。这是异步代码的本质。上面基本上是这样的:

  1. flag = canPlayerUseItem(player, itemId)
  2. 屈服直到本次事件循环迭代结束
  3. if (flag) ...(此时玩家可能不再登录)

如果您需要执行该检查,则必须在异步函数之外自行执行:

if (await Database.playerHasItem(player, itemId) && playersOnline.includes(player)) {
// As of this event loop, the player is online, and had the item
// when we checked a moment ago
}

这是:

  1. flag = Database.playerHasItem(player, itemId)
  2. 屈服直到本次事件循环迭代结束
  3. if (flag &&playersOnline.includes(player)...

关于javascript - Promise 返回值不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48732869/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com