【问题标题】:Implementing Promise Array with Try/Catch blocks within Typescript在 Typescript 中使用 Try/Catch 块实现 Promise 数组
【发布时间】:2018-08-14 02:30:56
【问题描述】:

我对 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;
}

【问题讨论】:

    标签: javascript typescript asynchronous promise


    【解决方案1】:

    您可以在第一个函数中使用 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

    一些观察:

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

    【讨论】:

    • 我看到您将 Try/Catch 拉到了 ExampleCall 函数中。当假设 10 个 AJAX 调用中有 1 个抛出异常时会发生什么。是否所有 10 个承诺都失败了,我没有得到任何结果?
    • 如果单个承诺失败,那么是的,它会抛出一个错误。为避免这种情况,您可以直接将 .catch(function(e){(/*..*/}) 附加到 ajaxResult。
    • Try/Catch 是否应该是 MultipleAsyncCalls,这样一个失败不会导致所有其他 AJAX 请求都显示为失败?
    • 这行不通,因为您没有在 MultipleAsyncCalls 中的任何地方等待,只需在循环中写入 resultSet.push(ajaxResult.catch(function(e){/*handle error*/}));,或者在 MultipleAsyncCalls 中等待每个承诺并在 await 周围使用 try/catch。我强烈建议您阅读以下页面:developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/… 和这个developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
    【解决方案2】:

    您可能想要的是Promise.all()。您将Promises 的数组传递给该方法,它将等到所有这些都已解决(或任何一个被拒绝)。您还可以传递带有参数的回调,该参数将填充来自每个 Promise 的所有已解析数据的数组。

    Link to Promise.all() for more info.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-19
      • 2011-04-17
      • 1970-01-01
      • 2015-01-07
      • 2021-03-17
      • 1970-01-01
      相关资源
      最近更新 更多