我有某些功能要求我进行一次api调用以检索在第二次api调用中使用的某些id,逻辑上它看起来像这样:
componentWillMount () {
this.props.functionOne()
// Wait for functionOne to complete before calling this
this.props.functionTwo(this.props.paramFromFunctionOne)
}
其中this.props.paramFromFunctionOne
是一旦函数一完成就存储在redux状态的东西。
答案 0 :(得分:2)
您可能希望使用redux-saga。 Redux saga专门用于调用异步函数和处理副作用。
例如,您可能希望在获取数据时在UI上显示加载程序图标。然后在收到数据后隐藏加载程序图标。您可以使用Redux-saga将此异步活动转换为同步活动。
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样板,你可以看到这段代码"看起来"绝对同步!
解密给定代码 -
将dataLoadRequest()
发送到redux商店。 (在UI上显示加载程序)。
向API请求数据。
dataLoadFailure()
操作。dataLoadSuccess()
操作。 Redux-saga使用ES6生成器功能。 yield
关键字是生成器函数的一部分。 function*
表示它是生成器函数而不是正常的javascript函数。
希望这会有所帮助。祝你好运!
答案 1 :(得分:2)
正如我所理解的那样,你可以这样做:
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)
});
}