saga js 的异步操作
Async actions with saga js
我正在调度一个动作,这是对我的 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,以及保存到存储的缩减程序。但是,我的理解是可以将适当的异步逻辑放在 saga 文件中吗?最好的方法是什么?谢谢!
好吧,您可以在 createNote
观察者内的 finally
块中调度 NOTES_FETCH
操作。
鉴于 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
}
我正在调度一个动作,这是对我的 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,以及保存到存储的缩减程序。但是,我的理解是可以将适当的异步逻辑放在 saga 文件中吗?最好的方法是什么?谢谢!
好吧,您可以在 createNote
观察者内的 finally
块中调度 NOTES_FETCH
操作。
鉴于 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
}