我正在尝试为我的学习项目做战斗循环,最后我意识到我需要一些异步等待/答应,因为这是场景:
双方各有4名战士。在这种情况下,一切都会顺利进行,因为敌人会随机选择一个角色进行攻击,并且功能会按预期进行。
但是,您的角色会死,然后我们只剩下3个,但是我没有从角色数组中删除它们,因为它们可以在以后恢复,因此敌人仍然掷出k4,以防他们得到指数已经死亡的角色,他们需要再次滚动。
理论上,我以为我知道自己在做什么,但是实际上我没有定义,因为(以我的假设)其他功能不会等待敌人选择要攻击的角色的索引,而在角色滚动的同时执行和程序崩溃。
这是敌人转弯处的一些代码:
enemies.forEach((enemy, i) => {
setTimeout( async () => {
let allyIndex = await dispatch(getAllyIndex());
let enemyAgility = getEnemyAgility(i, enemies);
let allyEvasion = await dispatch(getAllyEvasion(allyIndex));
let wasAttackSuccessful = await dispatch(calculateAttackSuccessChance(enemyAgility, allyEvasion));
if (wasAttackSuccessful) {
let wasCritical = dispatch(wasAttackCritical(i));
let enemyDmg = dispatch(calculateEnemyDmg(i));
let allyDef = await dispatch(getAllyDefence(allyIndex));
let totalDmg = await dispatch(calculateTotalDmg(enemyDmg, allyDef, wasCritical));
let info = ``;
if (wasCritical) { info += `Critical hit! ` };
let allyName = await getState().characters[allyIndex].name;
info += `${enemy.name} dealth ${totalDmg} damage to ${allyName}.`;
dispatch(addInfoToArray(info))
dispatch(allyLoseHp(totalDmg, allyIndex))
} else {
let info = `${enemy.name} missed!`
dispatch(addInfoToArray(info))
}
noOfEnemiesAttacked += 1;
if (noOfEnemiesAttacked === enemies.length) {
dispatch(changeTurn('ally'))
}
}, 2000 + offset);
offset += 200;
})
问题可能出在getAllyIndex函数中。外观如下:
const getAllyIndex = () => {
return function (dispatch, getState) {
let i = Math.floor((Math.random() * getState().characters.length));
if (getState().characters[i].stats.hp <= 0) {
dispatch(getAllyIndex());
} else {
return i;
}
}
}
程序会报告那些需要allyIndex的函数中的错误:
let allyEvasion = await dispatch(getAllyEvasion(allyIndex));
let allyDef = await dispatch(getAllyDefence(allyIndex));
let allyName = await getState().characters[allyIndex].name;
我是否完全误解了异步等待的概念,还是问题出在其他地方?
答案 0 :(得分:0)
.forEach()中存在异步/等待问题,例如:Using async/await with a forEach loop
您尝试用普通的for循环替换它吗?
答案 1 :(得分:0)
看起来您正在递归调度getAllyIndex
,但是通过redux递归调度异步操作可能与常规函数不同。难道这根本就必须是一个动作创建者,因为它的返回不包含任何商店更新?
您是否尝试过使用普通函数?如果您需要访问状态,则可以考虑删除递归部分或仅导入存储并使用store.getState()
(这是一个错误的模式,但可能适合您的情况)
const getAllyIndex = () => {
return function (dispatch, getState) {
const characters = getState().characters;
const getRandomId = () => {
const i = Math.floor((Math.random() * characters.length));
if (characters[i].stats.hp <= 0) {
getRandomId();
} else return i;
}
return getRandomId();
}
}