调用函数"step by step"的正确方法



我有一个特定的功能,需要我做一个api调用来检索在第二个api调用中使用的特定id,逻辑上它看起来像这样:

componentWillMount () {
  this.props.functionOne()
  // Wait for functionOne to complete before calling this
  this.props.functionTwo(this.props.paramFromFunctionOne)
}

其中this.props.paramFromFunctionOne是函数1完成后以redux状态存储的东西

根据我的正确理解,您可以这样实现:

componentWillMount () {
  // As `axios` returns promise, you should return it from `functionOne`
  // This way you can be able to use `.then` method.
  this.props.functionOne()
    .then(() => {
      // This code block would be executed after api call from first function will be finished.
      this.props.functionTwo(this.props.paramFromFunctionOne)
    });
}

您可能需要使用redux-saga。Redux saga专门用于调用异步函数和处理副作用。

例如,您可能希望在获取数据时在UI上显示加载器图标。然后在收到数据后隐藏加载器图标。您可以使用Redux-saga将此异步活动转换为同步活动。

例子传奇——

import { take, call, put, fork, cancel, race } from 'redux-saga/effects';
import { delay } from 'redux-saga';
import { LOCATION_CHANGE } from 'react-router-redux';
import { DATA_LOAD_REQUEST } from './constants';
import { dataLoadSuccess, dataLoadFailure } from './actions';
import request from 'utils/request'; //isomorphic-fetch
export function* getCompanies() {
  const requestURL = 'https://api.myjson.com/bins/32rap';
  const { companies, timeout } = yield race({
    companies: call(request, requestURL),
    timeout: call(delay, 10000),
  });
  if (companies) {
    yield put(dataLoadSuccess(companies.data));
  } else if (timeout) {
    yield put(dataLoadFailure());
  } else {
    yield put(dataLoadFailure());
  }
}
export function* getCompaniesWatcher() {
  while (yield take(DATA_LOAD_REQUEST)) {
    yield call(getCompanies);
  }
}
export function* companiesData() {
  const watcher = yield fork(getCompaniesWatcher);
  yield take(LOCATION_CHANGE);
  yield cancel(watcher);
}
// All sagas to be loaded
export default [
  companiesData,
];

一开始你可能会觉得难以置信。让我一点一点地解释。如果忽略redux-saga样板文件,可以看到这段代码"看起来"是完全同步的!

破译给定代码-

  1. dataLoadRequest()分派到redux store。

  2. 处理超时(如果10秒内没有加载数据,将dataLoadFailure()动作调度到redux store)
  3. 如果收到数据,向store调度dataLoadSuccess()动作

Redux-saga使用ES6生成器函数。yield关键字是生成器函数的一部分。function*表示它是一个生成器函数,而不是普通的javascript函数。

希望这对你有帮助。好运!

最新更新