我在TypeScript中有以下服务从后端获取数据。
作为函数getAllPropertiesByAppId的参数,我有一个成功和错误回调。
export class PropertyService implements IPropertyService {
/**
* Get all properties
*/
public getAllPropertiesByAppId(appliactionId: string, success: (properties: Array<IPropertyItem>) => void, error: (error: any) => void): void {
//set up createRequestStr and requestInit
fetch(createRequestStr, requestInit)
.then<IPropertyItem[]>((response: Response) => {
if (response.status===401) {
throw new UnAuthorizedException();
}
return response.json<IPropertyItem[]>();
})
.then((response: IPropertyItem[]) => {
success(response);
})
.catch((reason: any) => {
//error handling
}
});
}
然后我在我的动作创建者中使用此服务:
initProperties: (appId: string): ActionCreator => (dispatch: Redux.Dispatch, getState: () => IApplicationState) => {
"use strict";
console.log("ShoppingCart initProperties - Request all Property");
var service: IPropertyService = kernel.get<IPropertyService>("IPropertyService");
service.getAllPropertiesByAppId(appId, (properties: Array<IPropertyItem>): void => {
dispatch(new ShoppingCartPropertiesLoaded(appId, properties));
dispatch(new ShoppingCartPropertiesDone(appId, System.Init.Done));
}, (error: any): void => {
console.log("ShoppingCart initProperties - error:" + error);
dispatch(new ShoppingCartPropertiesDone(appId, System.Init.Error));
});
}
因此,当我调用initProperties动作创建器时,它调用getAllPropertiesByAppId,当一切正常时,我将调度ShoppingCartPropertiesLoaded和ShoppingCartPropertiesDone。
我有一个连接到store的简单组件,当执行render方法时组件会抛出错误
export default class TotalPriceList extends React.Component<ITotalPriceListProps, void> {
public render(): JSX.Element {
throw 'SomeError';
}
}
未处理的异常最终出现在fetch的catch语句中。
我是否遗漏了如何正确退出promise甚至更好地如何从语句和退出promise中调用函数/回调,以避免在fetch的catch语句中从回调中捕获异常?
非常感谢你的帮助
答案 0 :(得分:2)
作为函数getAllPropertiesByAppId的参数,我有成功和错误回调。
那是你的实际问题。您应该始终从异步函数返回一个promise。 停止使用回调参数!
您的代码应该是
/**
* Get all properties
*/
public getAllPropertiesByAppId(appliactionId: string): Promise<IPropertyItem[]> {
//set up createRequestStr and requestInit
return fetch(createRequestStr, requestInit)
// ^^^^^^
.then<IPropertyItem[]>((response: Response) => {
if (response.status===401) {
throw new UnAuthorizedException();
}
return response.json<IPropertyItem[]>();
});
}
这会偶然解决您未经处理的拒绝问题。通过不结束链但返回承诺,你像往常一样将处理错误的责任放在调用者身上。此外,调用者隐含地负责他在他的承诺回调中所做的任何事情 - 他们根本不涉及承诺返回方法。
你因此使用
service.getAllPropertiesByAppId(appId).then((properties: Array<IPropertyItem>): void => {
// ^^^^^
dispatch(new ShoppingCartPropertiesLoaded(appId, properties));
dispatch(new ShoppingCartPropertiesDone(appId, System.Init.Done));
}, (error: any): void => {
console.log("ShoppingCart initProperties - error:" + error);
dispatch(new ShoppingCartPropertiesDone(appId, System.Init.Error));
}).catch((reason: any) => {
// error handling for a failed dispatch
});
答案 1 :(得分:0)
如果您不想在承诺链中捕获异常,则只需在最后删除.catch
来电。
但请记住,您将无法使用try {} catch (error) {}
块捕获此错误。相反,它会冒泡到最高级别会收到unhandledRejection
。
如果我理解正确,您将回调(success
)传递给getAllPropertiesByAppId
,它返回一个调用回调的承诺; fetch(…).then(success)
基本上。所以你所经历的完全是对promises中包含的函数内异常的定义行为。
您可能希望切换到使用promise,而不是混合连续传递样式(回调)和承诺。
像(伪代码js,而不是抱歉)
class Service {
getAllPropertiesByAppId (appId) {
return fetch(createRequestStr, requestInit)
.then(response => response.json());
}
};
// …
service.getAllPropertiesByAppId(…)
.then(dispatchAllTheThings)
.catch(error => { console.log(…); dispatch(…) })
在调用.catch
之后,在调度组件中抛出异常将被捕获到promise链中的dispatchAllTheThings
内。