redux 在mergemap/await中调度多个操作

kmbjn2e3  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(106)

我对redux-observable还是个新手,所以如果这是个愚蠢的问题,请原谅我。
基本上,我需要等待一些Promises,然后在史诗中调度多个动作。但是返回一个动作数组只会导致错误Actions must be plain objects. Instead, the actual type was: 'array',你可以从我的CodeSandbox中点击PING按钮来测试这个。
我知道这可以通过使用from()和pipe()等方法来解决,但是如果可能的话,我想保留try/catch和repeat/await的格式。
我试着用of()和from() Package 动作数组,但仍然是同样的错误
提前感谢任何可以帮助我的人。

3j86kqsm

3j86kqsm1#

您需要为mergeMap函数提供一致的返回类型。
因为它是一个promise/promise函数,所以它当前返回Promise<Action>Promise<Action[]>,而且你不可能从promise /promise函数中发出两个值。
然后,你得到的observable将是一个Observable<Action | Action[]>,但redux observable需要Action,而不需要数组。
在我看来,如果你想保留Observable<Action[]>函数,最好的解决方案是让它始终返回Promise<Action[]>,然后在原始mergeMap(array => array)之后添加一个额外的mergeMap(array => array),将Observable<Action[]>转换为Observable<Action>

mergeMap(async (action: any) => {
  try {
    // I need to call some APIs here
    const res1 = await axios.get(
      "https://jsonplaceholder.typicode.com/posts"
    );

    const res2 = await axios.get(
      "https://jsonplaceholder.typicode.com/comments"
    );

    // Let's say an API throws an error
    throw new Error("Mock error");

    return [{
      type: PONG,
      data: res1.data
    }];
  } catch (error) {
    // On error, we should dispatch 2 actions
    return [
      {
        type: PONG,
        data: []
      },
      {
        type: HANDLE_ERROR,
        error: error
      }
    ];
  }
}),
mergeMap(array => array)

另一个可能的解决方案,这是有趣的,但可能有点复杂,是使用dsp生成器代替。这些函数可以产生(返回)多个值:

// Note the `*` meaning it's a generator function. Also can't be an arrow function
mergeMap(async function *(action: any) {
  try {
    // I need to call some APIs here
    const res1 = await axios.get(
      "https://jsonplaceholder.typicode.com/posts"
    );

    const res2 = await axios.get(
      "https://jsonplaceholder.typicode.com/comments"
    );

    // Let's say an API throws an error
    throw new Error("Mock error");

    yield {
      type: PONG,
      data: res1.data
    };
  } catch (error) {
    // On error, we should dispatch 2 actions
    yield {
      type: PONG,
      data: []
    };
    yield {
      type: HANDLE_ERROR,
      error: error
    };
  }
})

第二种解决方案我并不推荐,因为P2P生成器很难理解,而且它们在社区中也不太知名。

相关问题