使用react-boilerplate我有一个正确保存数据到服务器的传奇。我想发出延迟保存警告的警告(在完全超时之前)。为了模拟这个,我在服务器上等待了5秒钟,并在警告开始前等待了1秒钟。
我已经尝试了很多选项,但问题的关键是操作:在超时功能期间调度的 autoSaveTimeOutAction 在reducer函数中没有减少。
我的问题是为什么会发生这种情况?我怎样才能让它发挥作用?
这是我的输出:
10:26:04.523 client.js:62 [HMR] connected
10:26:06.722 sagas.js?7e80********:111 attemptAutoSaveSaga starts
10:26:06.722 actions.js:111 autoSaveInitiatedAction
10:26:07.725 actions.js:119 autoSaveTimeOutAction
10:26:11.890 actions.js:127 autoSaveSuccessAction
10:26:11.891 reducer.js:72 Reducer: ACTIONS.API.AUTOSAVE.SUCCESS
和代码摘录:
saga.js ....
export function* attemptAutoSaveSaga() {
let autoSaveTimeOut;
console.log('attemptAutoSaveSaga starts');
try {
const dataToSave = yield select(apiFirstNonSentSyncingSelector());
yield put(autoSaveInitiatedAction(dataToSave));
const url = `${API.URL}subjects/auto_save`;
const options = {
method: API.METHODS.POST,
credentials: 'include',
body: JSON.stringify(dataToSave),
};
autoSaveTimeOut = setTimeout(() => { put(autoSaveTimeOutAction(dataToSave)); }, 1000);
const payload = yield call(request, url, options);
yield (put(autoSaveSuccessAction(payload)));
clearTimeout(autoSaveTimeOut);
} catch (error) {
clearTimeout(autoSaveTimeOut);
...
}
}
export function* autoSaveSaga() {
const watcher = yield takeLatest(ACTIONS.API.AUTOSAVE.REQUESTED, attemptAutoSaveSaga);
yield take(LOCATION_CHANGE);
yield cancel(watcher);
}
reducer.js
...
case ACTIONS.API.AUTOSAVE.SUCCESS: {
console.log('Reducer: ACTIONS.API.AUTOSAVE.SUCCESS');
...
case ACTIONS.API.AUTOSAVE.TIMEOUT: {
console.log('Reducer: ACTIONS.API.AUTOSAVE.TIMEOUT');
return state;
}
...
actions.js
...
export function autoSaveInitiatedAction(payload) {
console.log('autoSaveInitiatedAction');
return ({
type: ACTIONS.API.AUTOSAVE.INITIATED,
payload,
});
}
export function autoSaveTimeOutAction(payload) {
console.log('autoSaveTimeOutAction');
return ({
type: ACTIONS.API.AUTOSAVE.TIMEOUT,
payload,
});
}
export function autoSaveSuccessAction(payload) {
console.log('autoSaveSuccessAction');
return {
type: ACTIONS.API.AUTOSAVE.SUCCESS,
payload,
};
}
...
答案 0 :(得分:0)
要解决此问题,我需要分叉延迟,根本不使用javascript超时,并在成功返回服务器数据时取消任务。
function* delayStart(dataToSave) {
yield call(delay, 1000);
yield put(autoSaveTimeOutAction(dataToSave));
}
export function* attemptAutoSaveSaga() {
let delayStartTask;
try {
const dataToSave = yield select(apiFirstNonSentSyncingSelector());
console.log('attemptAutoSaveSaga starts');
yield put(autoSaveInitiatedAction(dataToSave)); // this is to set sent and timestamp.
const url = `${API.URL}subjects/auto_save`;
const options = {
method: API.METHODS.POST,
credentials: 'include',
body: JSON.stringify(dataToSave),
};
delayStartTask = yield fork(delayStart, dataToSave);
const payload = yield call(request, url, options);
yield (put(autoSaveSuccessAction(payload)));
yield cancel(delayStartTask);
} catch (error) {
yield cancel(delayStartTask);
...