如何最小化 Angular JS 中收集所有承诺的延迟

How to minimize the delays in collecting all promises in Angular JS

请看下面我的代码。在 'for' 循环中,在每次迭代中,我都会进行 Ajax 调用并将承诺推入数组并使用 $q.all 解决所有这些承诺。但这会导致延迟,因为我需要等到 'for' 循环中收集到所有承诺,然后在所有承诺可用之后,我需要在 $q.all 中一一解决它们。

var promises = [];

for (var i = 0; i < dashboardslayoutArray.length; i++) {
    dashboardData.dashletteBeansList = [];
    dashboardData.dashletteBeansList[0] = dashboardslayoutArray[i];

    var dashlettePromise = DashboardsDataService.getTabDetails(dashboardData);
    promises.push(dashlettePromise);
}

$q.all(promises)
    .then(function(data) {
        // all promises were resolved here
    });

相反,我想做的是,尽快在 'for' 循环中解决承诺,而不是将其推入 'promises' 以在 $q.all 中使用。有些东西,

for (var i = 0; i < dashboardslayoutArray.length; i++) {
    dashboardData.dashletteBeansList = [];
    dashboardData.dashletteBeansList[0] = dashboardslayoutArray[i];

    var dashlettePromise = DashboardsDataService.getTabDetails(dashboardData);

    dashlettePromise.then(function(data) {
        ...
    }, function(error) {
        alert(error);
    });
}    

但这没有按预期工作。这里第二个承诺结果影响第一个承诺结果,等等。有什么解决办法吗?

根据@Benjamin Gruenbaum 的建议,我已将其更改为

angular.forEach(dashboardslayoutArray, function(dashboardslayout) {
    dashboardData.dashletteBeansList = [];
    dashboardData.dashletteBeansList[0] = dashboardslayout;

    var promise = DashboardsDataService.getTabDetails(dashboardData);

    promises.push(promise);

});

但是我怎样才能减少延迟呢?

@Benjamin Gruenbaum,我在下面总结我的问题:

var promises = [];
angular.forEach(dashboardslayoutArray, function(dashboardslayout) {
    dashboardData.dashletteBeansList = [];
    dashboardData.dashletteBeansList[0] = dashboardslayout;

    var promise = DashboardsDataService.getTabDetails(dashboardData);

    promises.push(promise);

});

$q.all(promises)
    .then(function(allData) {

        allData.forEach(function(data) {

            for (var dashVar = 0; dashVar < data.tabDetails.length; dashVar++) {
                var dashletteId = data.tabDetails[dashVar].dashletteId;
                var axisType = data.tabDetails[dashVar].axisType;
                // ...   draw c3 chart ...
            }
        });
    });

我需要进行多次 Ajax 调用,所以我使用了上述方法,效果很好。这里我所有的 Ajax 调用结果都是独立的,其中 none 取决于其他人。使用每个 Ajax 调用返回的数据,我使用 Angularjs C3 指令绘制图表。

但我面临的问题是延迟。要绘制四个 C3 图表,我需要进行四个 ajax 调用,使用 $q.all,只有在所有四个 Ajax 调用完成(解决或拒绝)后,我才能开始绘制 C3 图表。相反,我想做的是,很快任何一个 Ajax 调用结束(解决或拒绝),我想根据那个特定 Ajax 调用的结果开始绘制 C3 图表。所以我使用了以下方法来避免延迟排队所有的承诺。

angular.forEach(dashboardslayoutArray, function(dashboardslayout) {
    dashboardData.dashletteBeansList = [];
    dashboardData.dashletteBeansList[0] = dashboardslayout;

    var promise = DashboardsDataService.getTabDetails(dashboardData);

    promise.then(function(data) {

        for (var dashVar = 0; dashVar < data.tabDetails.length; dashVar++) {
            var dashletteId = data.tabDetails[dashVar].dashletteId;
            var axisType = data.tabDetails[dashVar].axisType;
            // ...   draw c3 chart ...
        }
    }, function(error) {
        alert(error);
    });

});

我的最后一个问题是,我在 angular.forEach(dashboardslayoutArray , function(dashboardslayout) 中使用 promise.then(function (data) 以避免延迟的方法是否正确?这种方法有什么潜在的问题吗?我希望,我已经清楚地表达了我的问题,如果没有请让我知道,我会尽量让 plunkr。

My final question is, is it right approach the way I have used promise.then(function (data) inside angular.forEach(dashboardslayoutArray , function(dashboardslayout) to avoid the delays?

是的,这正是您应该做的。 $q.all() 允许您在解决一整套承诺后做一些事情。由于这与您想做的相反,$q.all() 不是适合此处工作的工具。

您从未向我们展示您在第二个代码示例中 then() 中的内容,但鉴于您说 "second promise result effecting first promise result, etc",很可能Benjamin Gruenbaum 的怀疑是正确的,是 i 循环变量导致了问题。切换到 .forEach() 会解决这个问题。