Javascript 如何将api调用包装器从redux thunk迁移到redux saga
我最近开始使用redux saga,我真的很喜欢它 我有下面的包装器,用于我的api调用,它将接受承诺(我的api调用),并显示预加载程序和处理错误Javascript 如何将api调用包装器从redux thunk迁移到redux saga,javascript,reactjs,redux,redux-thunk,redux-saga,Javascript,Reactjs,Redux,Redux Thunk,Redux Saga,我最近开始使用redux saga,我真的很喜欢它 我有下面的包装器,用于我的api调用,它将接受承诺(我的api调用),并显示预加载程序和处理错误 export const callApi = (promise: Promise<any>, errorMsg: string = 'Api error') => (dispatch: Dispatch) => { dispatch(setLoading(true)); return promise.then(
export const callApi = (promise: Promise<any>, errorMsg: string = 'Api error') => (dispatch: Dispatch) => {
dispatch(setLoading(true));
return promise.then(
(response) => {
dispatch(setLoading(false));
return response.body;
},
(error) => {
dispatch(setLoading(false));
dispatch(apiError(errorMsg, error));
return error;
});
};
export const callApi=(promise:promise,errorMsg:string='Api error')=>(dispatch:dispatch)=>{
调度(设置加载(真));
回报你的承诺(
(回应)=>{
调度(设置加载(假));
返回响应.body;
},
(错误)=>{
调度(设置加载(假));
调度(apiError(errorMsg,error));
返回误差;
});
};
我不确定如何在redux传奇中复制这样的行为。我找不到这样做的例子
到目前为止,我已经想出了
const camelizeKeysPromise = (obj) => Promise.resolve(camelizeKeys(obj));
export function* sagaCallApi(promise: Promise<any>, errorMsg: string = 'Api error') {
yield put(setLoading(true));
try {
const response = yield call(promise);
try {
const result = yield call(camelizeKeysPromise(response.body));
return result;
} catch (e) {
return response.body;
}
} catch (exception) {
yield put(setLoading(false));
yield put(apiError(errorMsg, error));
};
}
const camelizeKeysPromise=(obj)=>Promise.resolve(camelizeKeys(obj));
导出函数*sagacalapi(promise:promise,errorMsg:string='Api error'){
屈服put(设定载荷(真));
试一试{
常量响应=收益调用(承诺);
试一试{
const result=yield调用(camelizeKeysPromise(response.body));
返回结果;
}捕获(e){
返回响应.body;
}
}捕获(例外){
屈服put(设置加载(假));
产量投入(APIRROR(errorMsg,error));
};
}
产生一个呼叫
承诺将不会返回所需的响应。您可以使用redux saga
中的eventChannel
创建一个在成功时发出响应或在失败时发出错误对象的频道,然后订阅saga中的频道
const promiseEmitter = promise => {
return eventChannel(emit => {
promise.then(
response => emit({response}),
error => emit({error})
);
});
};
修改您的新传奇,用以下内容取代对承诺的呼唤:
const channel = yield call(promiseEmitter, promise);
const {response, error} = yield take(channel);
if(response){
// handle success
return response;
}else if(error){
// handle failure
yield put(setLoading(false));
yield put(apiError(errorMsg, error));
}
请注意,当我在没有编辑器的情况下编写本文时,我的代码中可能存在语法错误,但您可以使用一般方法 谢谢你的回答。我刚刚在频道上读了些东西。如果我传递了一个函数返回一个承诺,而不是一个承诺,那么就不需要这样做了。你可能会遇到同样的问题,因为如果你对该函数产生调用效果,你将得到承诺而不是响应,除非我不理解你的问题。