代码之家  ›  专栏  ›  技术社区  ›  Alexander Abakumov

使用async\await重写基于承诺的代码

  •  1
  • Alexander Abakumov  · 技术社区  · 6 年前

    我想重写这个 Promise -基于代码的使用 async \ await :

    public loadData(id: string): void {
        this.loadDataAsync()
            .then((data: any): void => {
                 // Do something with data
            })
            .catch((ex): void => {
                 // Do something with ex
            });
    }
    
    public loadDataAsync(): Promise<any> {
        // return Promise somehow
    }
    

    我到目前为止重写的代码是:

    public loadData(id: string): void {
        let data: any;
    
        try {
            data = await this.loadDataAsync();
        } catch(ex) {
             // Do something with ex
        }
    
        // Do something with data
    }
    
    public async loadDataAsync(): Promise<any> {
        // return Promise somehow
    }
    

    问题是我必须 loadData() 方法 异步 因为它一直在它的身体里等待。那么,我得还一些 承诺 从那以后 异步 方法必须返回 承诺 . 但我需要维护 加载数据() 方法与回报 void .

    我怎样才能做到这一点?你如何打破一个永无止境的需要,使一个方法 异步 当内心深处呼唤你的时候 异步 方法?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Asleepace    6 年前

    理想情况下,如果您可以更改函数声明,只需添加 async 关键字到 loadData 使用 await 里面是这样的:

    public async loadData(id: string): void {
        let data: any;
    
        try {
            data = await this.loadDataAsync();
        } catch(ex) {
             // Do something with ex
        }
    }
    

    如果您无法更改 装载数据 函数声明,然后您可以创建一个匿名 异步 函数,然后调用 等待 在匿名函数中,如下所示:

    public loadData(id: string): void {
        let data: any;
    
        try {
            data = (async () => { return await this.loadDataAsync() })();
        } catch(ex) {
             // Do something with ex
        }
    }
    
    public async loadDataAsync(): Promise<any> {
        return new Promise((resolve, reject) => {
            // Logic goes here
            resolve(data);
        });
    }
    

    每当你使用 等待 关键字,周围的函数必须标记为 异步 .


    正如OP在评论中指出的,在TypeScript中,最好将promise return方法标记为 异步 以及(参见 loadDataAsync 上面的函数),因为这样可以确保返回类型始终是promise。更多信息请参见:

    TypeScript Async / Await Tutorial