【问题标题】:Asynchronous api calls with redux-saga使用 redux-saga 进行异步 api 调用
【发布时间】:2016-12-12 00:44:35
【问题描述】:

我在 helpers 上关注redux-saga documentation,到目前为止看起来很简单,但是在执行 api 调用时我偶然发现了一个问题(您将看到指向此类示例的文档链接)

Api.fetchUser 的一部分没有解释,因此我不明白这是否是我们需要使用诸如 axiossuperagent 之类的库处理的事情?或者是别的什么。像call, put 这样的传奇效果是get, post 的等价物吗?如果是这样,他们为什么这样命名?本质上,我试图找出一种正确的方法来在 url example.com/sessions 处对我的 api 执行简单的 post 调用,并将其传递给 { email: 'email', password: 'password' } 之类的数据

【问题讨论】:

    标签: javascript api reactjs redux redux-saga


    【解决方案1】:

    Api.fetchUser是一个函数,应该在哪里执行api ajax调用,它应该返回promise。

    在你的情况下,这个承诺应该解决用户数据变量。

    例如:

    // services/api.js
    export function fetchUser(userId) {
      // `axios` function returns promise, you can use any ajax lib, which can
      // return promise, or wrap in promise ajax call
      return axios.get('/api/user/' + userId);
    };
    

    然后是传奇:

    function* fetchUserSaga(action) {
      // `call` function accepts rest arguments, which will be passed to `api.fetchUser` function.
      // Instructing middleware to call promise, it resolved value will be assigned to `userData` variable
      const userData = yield call(api.fetchUser, action.userId);
      // Instructing middleware to dispatch corresponding action.
      yield put({
        type: 'FETCH_USER_SUCCESS',
        userData
      });
    }
    

    callput 是效果创建者功能。他们不熟悉GETPOST 请求。

    call函数用于创建效果描述,指示中间件调用promise。 put 函数创建效果,在其中指示中间件将操作分派到商店。

    【讨论】:

    • 记住错误处理 try{ const userData= .....yield... }catch (e) { yield put({ type: 'FETCH_USER_FAILED' }); }
    【解决方案2】:

    callputtakerace 之类的东西是效果创建函数。 Api.fetchUser 是您自己处理 API 请求的函数的占位符。

    这是 loginSaga 的完整示例:

    export function* loginUserSaga() {
      while (true) {
        const watcher = yield race({
          loginUser: take(USER_LOGIN),
          stop: take(LOCATION_CHANGE),
        });
    
        if (watcher.stop) break;
    
        const {loginUser} = watcher || {};
        const {username, password} = loginUser || {};
        const data = {username, password};
    
        const login = yield call(SessionService.login, data);
    
        if (login.err === undefined || login.err === null && login.response) {
          yield put(loginSuccess(login.response));
        } else {
          yield put(loginError({message: 'Invalid credentials. Please try again.'}));
        }
      }
    }
    

    在这个 sn-p 中,SessionService 是一个实现 login 方法的类,该方法处理对 API 的 HTTP 请求。 redux-saga call 将调用此方法并将 data 参数应用于它。在上面的 sn-p 中,我们可以评估调用结果并使用 put 相应地调度 loginSuccessloginError 操作。

    附注:上面的 sn-p 是一个 loginSaga,它持续监听 USER_LOGIN 事件,但在 LOCATION_CHANGE 发生时中断。这要感谢race 效果创建者。

    【讨论】:

      最近更新 更多