首页 > 解决方案 > 从一个 redux-saga 调用两种不同的动作类型

问题描述

我现在已经能够完成基本的 sagas 实现,但我的应用程序变得有点复杂了。我为异步功能选择了 sagas,但似乎误解了事物的工作原理。

我的应用程序中有一个全局搜索输入,需要进行两个不同的 api 调用(不同的数据对象),但搜索输入也有它自己的加载状态,基于 api 调用的搜索/状态。基于此信息,这是应用程序的流程:

  1. 搜索发生(发送操作GLOBAL_SEARCH_REQUEST
  2. saga watcher for GLOBAL_SEARCH_REQUESTkicks off(将输入的 loading 设置为 true)
  3. 在那个传奇中 - 拨打电话以获取与搜索查询匹配的所有用户/订阅
  4. 成功时,将输入的加载设置为 false
  5. 失败时,设置错误

全局搜索请求传奇

function* globalSearchRequestSaga(action) {
  const { query } = action
  console.log(`searching subscriptions and users for : ${query}`)
  try {
    yield put(fetchUsersRequest(query))
    // call for the subscriptions (leaving it out for simplicity in this example)
    yield put(globalSearchSuccess(query))
  } catch (error) {
    console.log(`error: ${error}`)
    yield put(globalSearchFailure(error.message))
  }
}

fetch users saga 的样子

export function* fetchUsersRequestSaga(action) {
  const { query } = action
  const path = `${root}/users`
  try {
    const users = yield axios.get(path, { crossDomain: true })
    yield put(fetchUsersSuccess(query, users.data))
  } catch (error) {
    console.log(`error : ${error}`)
    yield put(fetchUsersFailure(query, error.message))
  }
}

(非常基础)

如果我这样做,就会出现一个问题,即在GLOBAL_SEARCH_SUCCESS用户请求完成之前执行操作(如果我也添加了订阅 api 调用,我想同样的事情)。我找到的一种解决方案是,如果我换行

yield put(fetchUsersRequest(query))

yield call(fetchUsersRequestSaga, fetchUsersRequest(query))

fetchUsersRequestSaga上面的 saga在哪里,fetchUsersRequest(query)是获取用户的动作创建者。这会导致 asnyc 功能起作用,并GLOBAL_SEARCH_SUCCESS等待用户返回(正确行为)。

唯一的问题是该FETCH_USERS_REQUEST操作不再记录到存储中。

我想知道是否有办法让它正确登录到商店,或者返回到我以前的实现并正确阻止put(fetchUsersRequest(query))

标签: reactjsreduxredux-saga

解决方案


put函数是一个非阻塞动作。它不会等到 promise/api 请求解决。

我建议你直接调用 sagas 而不是调度动作。

try {
   yield call(fetchUsersRequestSaga, query);
   yield call(globalSearchSaga, query); // or whatever its called
}

call是一个阻塞动作。它会等到请求完成,所以如果你的调用都将按正确的顺序执行。


推荐阅读