使用saga js进行异步操作

时间:2019-02-13 03:28:11

标签: asynchronous redux redux-saga saga

我正在调度一个动作,这是对我的api(createNote)的put调用。

完成保存后,我需要运行另一个操作,这是对我的api的访存调用。

是否可以正确地等待第一个操作完成,然后再调用类似的设置(我现在通过saga使用异步操作而不使用setTimeout等)来设置其他操作?

form.js

function handleSubmit(id) {
  dispatch(createNote(obj));
  // need to wait for the above action to finish

  dispatch(notesFetch(id));
}

actions.js

export function createNote(obj) {
  return {
    type: CREATE_NOTE,
    payload: {
      obj: obj
    }
  };
}

export function notesFetch(id) {
  return {
    type: NOTES_FETCH,
    payload: id
  };
}

saga / index.js

const sagas = [
  createNote(),
  notesFetch(),
  // a bunch of other unrelated sagas in here as well
];

export default function* () {
  yield all(sagas);
}

saga / createNote.js

export function* createNote(action) {
  if (action['@@redux-saga/SAGA_ACTION']) return;

  const params = action.payload;

  try {
    yield *httpSaga(CREATE_NOTE, call(notesAPI.createNote, params));
  } catch (e) {
    yield put(error(CREATE_NOTE, e));
  } finally {
    yield put(doneIndicator(CREATE_NOTE));
  }
}

export function* watchCreateNote() {
  yield takeEvery(CREATE_NOTE, createNote);
}

export default function* root() {
  yield all([
    fork(watchCreateNote)
  ]);
}

saga / notesFetch.js

export function* notesFetch(action) {
  if (action['@@redux-saga/SAGA_ACTION']) return;

  try {
    yield *httpSaga(NOTES_FETCH, call(() => 
    notesAPI.getNotes(action.payload)));
  } catch (e) {
    yield put(error(NOTES_FETCH, e));
  } finally {
    yield put(doneIndicator(NOTES_FETCH));
  }
}

export function* watchNotesFetch() {
  yield takeEvery(NOTES_FETCH, notesFetch);
}

export default function* root() {
  yield all([
    fork(watchNotesFetch)
  ]);
}

然后,我在单独的api目录中有createNotes和notesFetch api调用,以及保存到商店的reducer。但是,我的理解是可以在saga文件中放置适当的异步逻辑吗?最好的方法是什么?谢谢!

1 个答案:

答案 0 :(得分:1)

好吧,您可以在NOTES_FETCH监视程序内的finally块中调度createNote动作。

鉴于该API没有任何订阅更新的方式。

// Saga
function* createNote(action) {
  try {
    // do something
  } finally {
    yield put(doneIndicator(CREATE_NOTE));
    yield put(notesFetch()); // also dispatch NOTES_FETCH here
  }
}

function* notesFetch(action) {
  // do something
}

export default function* root() {
  yield all([
    takeEvery(CREATE_NOTE, watchCreateNote),
    takeEvery(NOTES_FETCH, notesFetch),
  ]);
}

// Component
function handleSubmit(id) {
  dispatch(createNote(obj)); // only dispatch CREATE_NOTE action
}