我是否误解了异步等待? (函数不等待数据)

时间:2018-12-08 16:27:34

标签: javascript reactjs asynchronous redux

我正在尝试为我的学习项目做战斗循环,最后我意识到我需要一些异步等待/答应,因为这是场景:

双方各有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;

我是否完全误解了异步等待的概念,还是问题出在其他地方?

2 个答案:

答案 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();
  }
}