Redux:异步执行减速器?

Redux: Execute reducers asynchronously?

我正在研究保龄球计分系统,但我很困惑为什么以下系统没有按预期工作。

我的状态可能是这样的:

players: [
  {
    "id": "f44t0uagdyg",
    "name": "test-player",
    "currentFrame": 1,
    "active": false,
    "rolls": {
      "0": [2,3],
      "1": [1,5],
      "2": [],
      "3": [],
      "4": [],
      "5": [],
      "6": [],
      "7": [],
      "8": [],
      "9": [],
      "10": []
    },
    "totalWins": 0
  },
  {
    "id": "5gbxlu94zpr",
    "name": "test-player-2",
    "currentFrame": 1,
    "active": false,
    "rolls": {
      "1": [1,6],
      "2": [],
      "3": [],
      "4": [],
      "5": [],
      "6": [],
      "7": [],
      "8": [],
      "9": [],
      "10": []
    },
    "totalWins": 0
  }
]

现在,每当用户输入新的 roll 时,我都想将其添加到商店中 reducers(它们按预期工作): 要将卷添加到状态,我执行以下操作:

    case ADD_ROLL:
      return {
      ...state,
      players: state.players.map((player) => {
        if (player.id === action.id) {
          return {
            ...player,
            rolls: {
              ...player.rolls,
              [action.frame]: [
                ...player.rolls[action.frame],
                action.roll
              ]
            }
          }
        }
        return player;
      })
    };

要前进到下一帧(例如,在用户输入 2 次掷骰或掷一次攻击后),我这样做:

       case NEXT_FRAME:
          return {
          ...state,
          players: state.players.map((player) => {
            if (player.id === action.id) {
              return {
                ...player,
                currentFrame: player.currentFrame + 1,
              }
            }
            return player;
          })
        }

在用户点击确认他的输入后,这个 advanceGame 函数被调用以评估游戏是否应该前进到下一帧(如果用户已经滚动了两次):

export const advanceGame = (players, roll) => {
  let currentPlayer = 0;
  const { currentFrame } = players[currentPlayer];

  if (players[currentPlayer].rolls[currentFrame].length === 2) {
    store.dispatch(nextFrame(players[currentPlayer].id));
    store.dispatch(addRoll(players[currentPlayer].currentFrame, roll, players[currentPlayer].id));
  } else {
    store.dispatch(addRoll(players[currentPlayer].currentFrame, roll, players[currentPlayer].id));
  }
};

我希望发生的情况是,如果用户已经滚动了两次,store.dispatch(nextFrame)currentFrame 更新为下一个,然后 然后 将分数添加到适当的帧。但是,目前帧仅在进行了 3 次滚动并且 3 项在 roll 数组中后才会前进。

如何确保 ADD_ROLL 仅在 NEXT_FRAME 具有 'finished' 之后执行?

我已经盯着这个看了很长时间了,如果我的问题太冗长,我深表歉意。很高兴清理它并感谢任何帮助!

我不知道这是否正是您要找的,但我认为减速器总是同步的。

也许您可以尝试将操作设为异步。 Redux-thunk 是为 https://github.com/reduxjs/redux-thunk

制作的

例如,您可以调度一个执行 api 调用的操作,第二个操作仅在 api 已返回他的响应时才调用。

你应该找到需要时间执行的代码并将其替换在 thunk 中,并且只调用 reducer 来更新你的状态。