Асинхронные действия с сага JS - PullRequest
0 голосов
/ 13 февраля 2019

Я отправляю действие, которое является вызовом пут для моего API (createNote).

После завершения сохранения мне нужно запустить другое действие, которое является вызовом выборки для моего API.

Можно ли правильно дождаться завершения первого действия, прежде чем вызывать другие действия с аналогичной настройкой, которую я сейчас использую с помощью асинхронных действий через saga, без использования setTimeout и т. Д.?

форма.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, а также редукторы, которые сохраняются в магазине.Но, насколько я понимаю, можно поместить соответствующую асинхронную логику в файлы саги?Каков будет лучший способ пойти по этому поводу?Спасибо!

1 Ответ

0 голосов
/ 13 февраля 2019

Хорошо, вы можете отправить действие 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
}
...