【问题标题】:Uncaught Exception with async constructor pattern异步构造函数模式未捕获的异常
【发布时间】:2018-08-14 07:25:20
【问题描述】:

这个类有点特别,因为它在构造函数中使用了很多异步调用,而构造函数不能是异步的,所以我使用了我在互联网上读到的一种特殊模式:

export class MapLayer {
    public Ready: Promise<any>;

    constructor() {
        this.instantiate();
    }

    async instantiate(): Promise<void> {
        return this.Ready = new Promise((resolve, reject) => {
            this.parseServiceDefiniton().then(() => {
               // ...
               resolve(undefined);
            }).catch((ex) => {
                console.log('reject');
                reject();
            });
        });
    }

    async parseServiceDefiniton(): Promise<boolean> {
        throw Error('test');
    }

}

以及我如何使用它:

const lyr: MapLayer =  new MapLayer ();
    
     lyr.Ready.then(() => {
              
    
    }).catch(ex => {
       console.log(ex);
    });

由于parseServiceDefiniton 函数中可能发生异常,我正在模拟这种情况。目前,我收到以下错误:

未捕获(承诺中):[对象未定义]

在我看到的控制台中:

拒绝

未定义

我看不出哪里没有发现异常!

【问题讨论】:

    标签: typescript exception-handling promise


    【解决方案1】:

    问题是你在instantiate 中使用async。使async 成为可能的机制将创建另一个Promise,它将包装您返回的Promise,并且此承诺实际上不会捕获它的异常(因为您没有在构造函数中捕获错误)

    最简单的解决方案是删除async。由于您没有在正文中使用await,因此实际上不需要async

    export class MapLayer {
        public Ready!: Promise<any>;
    
        constructor() {
            this.instantiate();
        }
    
        instantiate(): Promise<void> {
            return this.Ready = new Promise((resolve, reject) => {
                this.parseServiceDefiniton().then(() => {
                    // ...
                    resolve(undefined);
                }).catch((ex) => {
                    console.log('reject');
                    reject(ex);
                });
            });
        }
    
        async parseServiceDefiniton(): Promise<boolean> {
            throw Error('test');
        }
    
    }
    
    const lyr: MapLayer = new MapLayer();
    
    lyr.Ready.then(() => {
    }).catch(ex => {
        console.log(ex);
    });
    

    或者一个使用异步且不需要使用Promise构造函数的版本:

    export class MapLayer {
        public Ready!: Promise<any>;
    
        constructor() {
            this.Ready = this.instantiate();
        }
    
        async instantiate(): Promise<void> {
            try {
                await this.parseServiceDefiniton()
            } catch (ex) {
                console.log('reject');
                throw ex;
            }
        }
    
        async parseServiceDefiniton(): Promise<boolean> {
            throw Error('test');
        }
    
    }
    
    const lyr: MapLayer = new MapLayer();
    
    lyr.Ready.then(() => {
    }).catch(ex => {
        console.log(ex);
    });
    

    【讨论】:

      猜你喜欢
      • 2020-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-29
      • 1970-01-01
      • 1970-01-01
      • 2013-09-07
      • 1970-01-01
      相关资源
      最近更新 更多