如何在 redux-saga 中使用 all effect 处理错误
How to deal with errors using all effect in redux-saga
我正在使用 redux-saga
并发启动多个请求,如 the redux-saga docs 中所述。 all
效果有一个 all or nothing semantics
,类似于 Promise.all
.
只有effects
全部成功,yield all([...])
才成功。但是,我正在执行几个请求,我希望其中一些请求失败,一些请求成功。我想并行启动所有这些并使用来自那些已成功请求的响应。
因此,我尝试将请求包装成一个 Promise
,无论请求是否成功,它总是解析:
// watcher saga
export function* watchMultipleRequests() {
while(true) {
const {ids} = yield take('VIDEOS_REQUEST');
yield fork(doMultipleRequests, ids);
}
}
// worker saga
export function* doMultipleRequests(ids) {
const requests = ids.map(id => {
// api.buildVideoRequest returns a promise once it is invoked
const wrapper = ignoreErrors(api.buildVideoRequest, id);
return call(wrapper);
});
try {
const responses = yield all(requests);
yield put({type: 'VIDEOS_SUCCESS', responses});
} catch (error) {
// should not happen because we are always resolving the promise
console.log(error);
}
};
export function ignoreErrors(fn, ...args) {
return function* () {
yield new Promise(function (resolve) {
return fn(...args)
.then(response => {
console.log('success = ', response);
resolve(response);
})
.catch(response => {
console.log('error = ', response);
resolve(response);
});
});
}
}
我想处理 reducer
中的错误案例。但是,如果我发出 n
请求,responses
数组包含 n
次 undefined
。有没有人知道为什么这不起作用?
问题是 ignoreErros 函数是一个生成器函数。
像这样实现它:
export function ignoreErrors(fn, ...args) {
return () => {
const ignoreErrorCallback = (response) => response;
return fn(...args).then(ignoreErrorCallback, ignoreErrorCallback);
};
}
足够了。
我正在使用 redux-saga
并发启动多个请求,如 the redux-saga docs 中所述。 all
效果有一个 all or nothing semantics
,类似于 Promise.all
.
只有effects
全部成功,yield all([...])
才成功。但是,我正在执行几个请求,我希望其中一些请求失败,一些请求成功。我想并行启动所有这些并使用来自那些已成功请求的响应。
因此,我尝试将请求包装成一个 Promise
,无论请求是否成功,它总是解析:
// watcher saga
export function* watchMultipleRequests() {
while(true) {
const {ids} = yield take('VIDEOS_REQUEST');
yield fork(doMultipleRequests, ids);
}
}
// worker saga
export function* doMultipleRequests(ids) {
const requests = ids.map(id => {
// api.buildVideoRequest returns a promise once it is invoked
const wrapper = ignoreErrors(api.buildVideoRequest, id);
return call(wrapper);
});
try {
const responses = yield all(requests);
yield put({type: 'VIDEOS_SUCCESS', responses});
} catch (error) {
// should not happen because we are always resolving the promise
console.log(error);
}
};
export function ignoreErrors(fn, ...args) {
return function* () {
yield new Promise(function (resolve) {
return fn(...args)
.then(response => {
console.log('success = ', response);
resolve(response);
})
.catch(response => {
console.log('error = ', response);
resolve(response);
});
});
}
}
我想处理 reducer
中的错误案例。但是,如果我发出 n
请求,responses
数组包含 n
次 undefined
。有没有人知道为什么这不起作用?
问题是 ignoreErros 函数是一个生成器函数。 像这样实现它:
export function ignoreErrors(fn, ...args) {
return () => {
const ignoreErrorCallback = (response) => response;
return fn(...args).then(ignoreErrorCallback, ignoreErrorCallback);
};
}
足够了。