Javascript 使用 redux-saga 进行异步 api 调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38791974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 21:51:06  来源:igfitidea点击:

Asynchronous api calls with redux-saga

javascriptapireactjsreduxredux-saga

提问by Ilja

I am following redux-saga documentationon helpers, and so far it seems pretty straight forward, however I stumbled upon an issue when it comes to performing an api call (as you will see link to the docs points to such example)

我正在关注关于帮助程序的redux-saga 文档,到目前为止它看起来非常简单,但是我在执行 api 调用时偶然发现了一个问题(你将看到指向此类示例的文档链接)

There is a part Api.fetchUserthat is not explained, thus I don't quiet understand if that is something we need to handle with libraries like axiosor superagent? or is that something else. And are saga effects like call, putetc.. equivalents of get, post? if so, why are they named that way? Essentially I am trying to figure out a correct way to perform a simple post call to my api at url example.com/sessionsand pass it data like { email: 'email', password: 'password' }

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

回答by 1ven

Api.fetchUseris a function, where should be performed api ajax call and it should return promise.

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

In your case, this promise should resolve user data variable.

在您的情况下,此承诺应解析用户数据变量。

For example:

例如:

// 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);
};

Then is sagas:

然后是传奇:

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
  });
}

call, putare effects creators functions. They not have something familiar with GETor POSTrequests.

call,put是效果创建器功能。他们没有熟悉GETPOST要求的东西。

callfunction is used to create effect description, which instructs middleware to call the promise. putfunction creates effect, in which instructs middleware to dispatch an action to the store.

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

回答by VanDanic

Things like call, put, take, raceare effects creator functions. The Api.fetchUseris a placeholder for your own function that handles API requests.

喜欢的东西callputtakerace是影响创作者的功能。该Api.fetchUser是你自己的函数,处理API请求的占位符。

Here's a full example of a loginSaga:

这是 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.'}));
    }
  }
}

In this snippet, the SessionServiceis a class that implements a loginmethod which handles the HTTP request to the API. The redux-saga callwill call this method and apply the data parameter to it. In the snippet above, we can then evaluate the result of the call and dispatch loginSuccessor loginErroractions accordingly using put.

在此代码段中,SessionService是一个实现login处理对 API 的 HTTP 请求的方法的类。redux-sagacall将调用此方法并将数据参数应用于它。在上面的代码中,我们可以评估呼叫和调度的结果loginSuccessloginError相应的使用行为put

A side note: The snippet above is a loginSaga that continuously listens for the USER_LOGINevent, but breaks when a LOCATION_CHANGEhappens. This is thanks to the raceeffect creator.

旁注:上面的代码片段是一个 loginSaga,它持续监听USER_LOGIN事件,但在LOCATION_CHANGE发生时中断。这要归功于race效果创建者。