如何知道异步调用已通过redux-saga完成?

时间:2019-07-13 14:33:28

标签: reactjs redux generator redux-saga

单击按钮后,我将调度一个操作以发出一个get请求,我想等待请求完成后再继续,什么是正确的方法? 我确实根据传奇中的结果调度了一个动作:

function* workerSaga() {
try {
  const response = yield call(fetchCall);
  const myData= response.data;

  // dispatch a success action to the store 
  yield put({ type: "API_CALL_SUCCESS", myData});

} catch (error) {
  // dispatch a failure action to the store with the error
  yield put({ type: "API_CALL_FAILURE", error });
}

但是我如何在分配请求动作的代码中知道get请求已完成?

提前谢谢。

编辑:

没有佐料的请求看起来像:

    axios.get(myURL)
    .then(/*here we know the request has finished*/);

佐贺传奇:

this.props.dispatch({type:"API_CALL"})
//here i would like to know the request has finished

2 个答案:

答案 0 :(得分:1)

this.props.dispatch({type:"API_CALL"})
//here i would like to know the request has finished

通常,这不是组件使用redux saga的方式。相反,应该使用react-redux的connect方法将您的组件预订到商店,因此,当API_CALL_SUCCESS经过reducer并更新状态时,您的组件将获得新的道具,从而重新渲染。如有必要,您可以实施componentDidUpdate以在prop更改时运行一些代码。

可以解决这个问题,以便您可以通过承诺来确定何时完成工作,但是这样做需要在组件和传奇之间引入更多的耦合,所以我建议不要在大多数情况下使用此功能。您可以设置操作,以便其有效负载的一部分是回调函数,然后由saga调用该函数。例如:

// In the saga
function* workerSaga(action) {
  try {
    const response = yield call(fetchCall);
    const myData = response.data;

    // dispatch a success action to the store 
    yield put({ type: "API_CALL_SUCCESS", myData});
    if (action.callback) {
      action.callback(myData);
    } 

  } catch (error) {
    // dispatch a failure action to the store with the error
    yield put({ type: "API_CALL_FAILURE", error });
  }
}

// in the component
componentDidMount() {
  this.props.dispatch({ type: 'API_CALL', callback: onFetchSuccess }); 
}

onFetchSuccess(data) {

}

或者,如果您想要一个承诺,则回调可以是新承诺的解析器:

componentDidMount() {
  const promise = new Promise((resolve) => {
    this.props.dispatch({ type: 'API_CALL', callback: resolve }); 
  });
  promise.then(data => {

  });
}

// or, with async/await:
async componentDidMount() {
  const data = await new Promise(resolve => 
    this.props.dispatch({ type: 'API_CALL', callback: resolve })
  );
}

答案 1 :(得分:0)

下面是使用try/catch

的示例
function* workerSaga() {

  try {
    const response = yield call(fetchCall);
    if (response.data) { // check based on what the your API returns
      const myData= response.data;
      // dispatch a success action to the store 
      yield put({ type: "API_CALL_SUCCESS", myData});
    } else {
      throw response;
    }

  } catch (error) {
    // dispatch a failure action to the store with the error
    yield put({ type: "API_CALL_FAILURE", error });
  }
}

没有try/catch

function* workerSaga() {
  const response = yield call(fetchCall);

  if (response.data) { // check based on what the your API returns
    const myData= response.data;

    // dispatch a success action to the store 
    yield put({ type: "API_CALL_SUCCESS", myData});
  } else {
    // dispatch a failure action to the store with the error
    yield put({ type: "API_CALL_FAILURE", error });
  }
}