首页 > 解决方案 > 在 Typescript 中使用 Try/Catch 块实现 Promise 数组

问题描述

我对 Typescript 中的 Promises 和 Async 还很陌生,我仍在尝试了解实现已定义功能的异步逻辑的最佳方法。

我想编写一个函数,其中包含一个循环,该循环将触发几个 AJAX 请求。对于等待所有 AJAX 请求完成然后返回数组的最佳方式,我有点难过。我想出了以下实现,但我想知道这种方式是否是最好的方法。我还想知道如果其中一个 AJAX 请求失败并进入catch块,这是如何处理的?Array 是否有null用于该特定迭代的对象?

public async MultipleAsyncCalls(): Promise<Promise<ItemInfo>[]> {
    let resultSet = new Array<Promise<ItemInfo>>();

    for (let item of ArrayOfItems) {
        try {
            let ajaxResult = $.ajax(<JQuery.AjaxSettings>{
                url: "GetInformation" + "/" + item.Id,
                method: 'GET'
            });
            resultSet.push(Promise<ItemInfo><any>ajaxResult);
        } catch (ex) {
            this.ShowNotification("Something went wrong with the AJAX result");
        }
    }

    return resultSet;
}

public async ExampleCall(controllerConfigs: Promise<IControllerConfiguration[]>): Promise<ItemInfo[]> {
    //This first await will be complete near instantly as it is the function call completion
    //promise and not the AJAX completion.
    let promiseArray = await this.MultipleAsyncCalls();

    //Wait for all of the AJAX promises to complete.
    Promise.all(promiseArray);

    //Is it correct to assume here that all promsies of Array are done and this next loop will be near instant?
    let itemArray = new Array<ItemInfo>();
    for (let itemPromise of promiseArray) {
        itemArray.push(await itemPromise);
    }

    return itemArray;
}

标签: javascripttypescriptasynchronouspromise

解决方案


你可以Promise.all(resultSet)在你的第一个函数中使用并返回它。

public MultipleAsyncCalls(): Promise<Promise<ItemInfo>[]> {
    // don't try/catch here, use the catch handler after the then
    let resultSet = new Array<Promise<ItemInfo>>();
    for (let item of ArrayOfItems) {
            let ajaxResult = $.ajax(<JQuery.AjaxSettings>{
                url: "GetInformation" + "/" + item.Id,
                method: 'GET'
            });
            resultSet.push(Promise<ItemInfo><any>ajaxResult);
    }
    return Promise.all(resultSet);
}

public async ExampleCall(controllerConfigs: Promise<IControllerConfiguration[]>): Promise<ItemInfo[]> {
    // it's here where you should try/catch
    try{
        let promiseArray = await this.MultipleAsyncCalls();
    }catch(e){
         // handle error
    }
    //await doesn't work like that, remove that line below
    // Promise.all(promiseArray);

    // all this is unecessary, you are not doing anything new with 
    // the elements of the promiseArray 
    // let itemArray = new Array<ItemInfo>();
    // for (let itemPromise of promiseArray) {
    //    itemArray.push(await itemPromise);
    // }

    return promiseArray;
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

一些观察:

async当函数不包含关键字时不需要使用关键字await,它没用,你的函数不会async所以不要在MultipleAsyncCalls中使用它


推荐阅读