Javascript 正确承诺处理成功和错误回调

Javascript 正确承诺处理成功和错误回调,javascript,reactjs,typescript,redux,Javascript,Reactjs,Typescript,Redux,我在TypeScript中有以下从后端获取数据的服务 作为函数getAllPropertiesByAppId的参数,我有一个成功和错误回调 export class PropertyService implements IPropertyService { /** * Get all properties */ public getAllPropertiesByAppId(appliactionId: string, success: (properties: Array<IProp

我在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
            }
        });
}
导出类PropertyService实现IPropertyService{
/**
*获取所有属性
*/
public getAllPropertiesByAppId(appliactionId:string,success:(properties:Array)=>void,error:(error:any)=>void):void{
//设置createRequestStr和requestInit
获取(createRequestStr、requestInit)
.然后((响应:响应)=>{
if(response.status==401){
抛出新的UnAuthorizedException();
}
返回response.json();
})
。然后((响应:IPropertyItem[])=>{
成功(回应);
})
.catch((原因:任何)=>{
//错误处理
}
});
}
然后我在我的action creator中使用此服务:

 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:(appId:string):ActionCreator=>(dispatch:Redux.dispatch,getState:()=>iaapplicationstate)=>{
“严格使用”;
log(“ShoppingCart initProperties-请求所有属性”);
var服务:IPropertyService=kernel.get(“IPropertyService”);
service.getAllPropertiesByAppId(appId,(属性:数组):void=>{
调度(新ShoppingCartPropertiesLoaded(appId,properties));
分派(新ShoppingCartPropertiesDone(appId,System.Init.Done));
},(错误:any):void=>{
log(“ShoppingCart initProperties-error:+error”);
调度(新ShoppingCartPropertiesDone(appId,System.Init.Error));
});
}
因此,当我调用initProperties action creator时,它将调用getAllPropertiesByAppId,当一切正常时,我将调度操作ShoppingCartPropertiesLoaded和ShoppingCartPropertiesDone

我有一个简单的组件连接到store,当render方法执行时,该组件将抛出错误

export default class TotalPriceList extends React.Component<ITotalPriceListProps, void> {

public render(): JSX.Element {

    throw 'SomeError';
}
}
导出默认类TotalPriceList扩展React.Component{
public render():JSX.Element{
抛出“某些错误”;
}
}
未处理的异常在fetch的catch语句中结束

我是否错过了一些东西,比如如何正确地退出承诺,或者更好地如何从than语句调用函数/回调,以及退出承诺,以避免在fetch的catch语句中从回调中捕获异常


非常感谢您的帮助

如果您不想捕获承诺链中的异常,您只需在末尾删除
.catch
调用即可

但是请记住,您将无法使用
try{}catch(error){}
块捕获此错误。相反,它将冒泡到您将在顶层收到一个
未处理的弹出

如果我理解正确,您正在将回调(
success
)传递给
getAllPropertiesByAppId
,它返回调用回调的承诺<代码>获取(…)。然后(成功)基本上。因此,您所体验到的完全是承诺中包含的函数中定义的异常行为

您可能希望切换到始终使用承诺,而不是混合使用继续传递样式(回调)和承诺

类似(在伪代码js中,不是ts sorry)

类服务{
getAllPropertiesByAppId(appId){
返回获取(createRequestStr、requestInit)
.then(response=>response.json());
}
};
// …
service.getAllPropertiesByAppId(…)
.然后(分派所有内容)
.catch(错误=>{console.log(…);dispatch(…)})
调用
dispatchAllThings
后,在已调度组件内引发异常将在承诺链中的
.catch
内被捕获

作为函数getAllPropertiesByAppId的参数,我有成功和错误回调

这才是你真正的问题。您应该始终从异步函数返回承诺。 停止使用回调参数

你的代码应该是

/**
 * 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[]>();
    });
}
/**
*获取所有属性
*/
public getAllPropertiesByAppId(appliactionId:string):承诺{
//设置createRequestStr和requestInit
返回获取(createRequestStr、requestInit)
//  ^^^^^^
.然后((响应:响应)=>{
if(response.status==401){
抛出新的UnAuthorizedException();
}
返回response.json();
});
}
这将顺便解决您未处理的拒绝问题。通过不终止链而是返回承诺,您将处理错误的责任推到了调用方身上——就像往常一样。此外,调用方对其承诺回调中所做的任何事情都负有隐式责任——它们根本不涉及承诺返回方法

因此,您将使用

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
});
service.getAllPropertiesByAppId(appId)。然后((属性:数组):void=>{
//                                    ^^^^^
调度(新ShoppingCartPropertiesLoaded(appId,properties));
分派(新ShoppingCartPropertiesDone(appId,System.Init.Done));
},(错误:any):void=>{
log(“ShoppingCart initProperties-error:+error”);
调度(新ShoppingCartPropertiesDone(appId,System.Init.Error));
}).catch((原因:任何)=>{
//失败分派的错误处理
});

perfect这正是我想要的!谢谢你,伯吉!