AngularJS 中的链式承诺

Posted

技术标签:

【中文标题】AngularJS 中的链式承诺【英文标题】:Chained promises in AngularJS 【发布时间】:2015-07-08 17:49:03 【问题描述】:

我认为我是个白痴。这里发生了什么?为什么没有 i:0 或 i:1,只有最后一个?它表明它循环了所有内容,并且在循环后它尝试保存并且它多次保存相同的最后一个对象,之后我会得到错误 500,DB 中的重复键。是否可以在 AngularJS 中的 for 循环中保存对象:)?

在 console.log 中:

reasonList.length: 2
rma.js: 284 i: 2
rma.js: 285 defectdescDefectdescId: 2
rma.js: 286 returnreasonId: 1
rma.js: 287 rmaId: 15

代码:

        savedRma = rmaService.save(, rma);
        savedRma.$promise.then(function (result) 
            $scope.rma = result;
            console.log('result.rmaID--------->' + result.rmaId);
            saveReturnReason(result.rmaId);
        , function (error) 
            alert('Error in saving rma' + error);
        );
        $location.path('/rma-preview/' + $scope.rma.rmaId);
        rmaDataService.setRma($scope.rma);
    
; // ELSE CREATE RMA END
function saveReturnReason(rmaId) 
    for (var i = 0; i < $scope.reasonList.length; i++) 
        $scope.rmaHasDefectdesc.rmaHasDefectdescPK.defectdescDefectdescId = $scope.reasonList[i].defectdescId;
        $scope.rmaHasDefectdesc.rmaHasDefectdescPK.returnreasonId = $scope.reasonList[i].returnreasonReturnreasonId.returnreasonId;
        $scope.rmaHasDefectdesc.rmaHasDefectdescPK.rmaId = rmaId;
        savedRmaHasDefectdesc = rmaDefectSvc.save(, $scope.rmaHasDefectdesc);
        savedRmaHasDefectdesc.$promise.then(function (response) 
            $scope.savedRmaHasDefectdesc = response;
            console.log('i: ' + i)
            console.log('defectdescDefectdescId:' + response.rmaHasDefectdescPK.defectdescDefectdescId);
            console.log('returnreasonId:' + response.rmaHasDefectdescPK.returnreasonId);
            console.log('rmaId:' + response.rmaHasDefectdescPK.rmaId);
        , function (error) 
            alert('Error in saving reasons' + error);
        );
     // For loop ending
;

更新 forEach 我将 for 循环更新为 forEach。同样的结果,没有运气。仍然不会承诺。然后首先每个然后尝试多次保存最后一个原因。

function saveReturnReason(rmaId) 
    $scope.reasonList.forEach(function(reason)
    $scope.rmaHasDefectdesc.rmaHasDefectdescPK.defectdescDefectdescId = reason.defectdescId;
    $scope.rmaHasDefectdesc.rmaHasDefectdescPK.returnreasonId = reason.returnreasonReturnreasonId.returnreasonId;
    $scope.rmaHasDefectdesc.rmaHasDefectdescPK.rmaId = rmaId;
    console.log('rmaId: ' +rmaId+': returnReasonId: ' +reason.returnreasonReturnreasonId.returnreasonId +' defectID: '+reason.defectdescId);

    savedRmaHasDefectdesc = rmaDefectSvc.save(, $scope.rmaHasDefectdesc);
    // At the first loop, never comes to .then
    savedRmaHasDefectdesc.$promise.then(function (response) 
         $scope.savedRmaHasDefectdesc = response;

     , function (error) 
                            alert('Error in saving reasons' + error.status);
     );


     );// ForEach ending

;

【问题讨论】:

如果您正确格式化此代码会更好。 看起来像典型的“for循环中的异步工作,为什么i在回调中显示最后一个索引而不是当前索引” 请分享格式更好的代码以及此代码的输出。 可能重复:***.com/questions/750486/… 在 es6 浏览器上,将 var i 替换为 let i 应该可以解决问题,但是,要支持旧版浏览器,您必须切换到 Array.forEach,或者使用 iife 或for 循环中的函数生成器,以在每次迭代时将i 的值保留在新范围内。可能重复的最高投票答案显示所有三个选项。 【参考方案1】:

限定i,使其仅在循环中可用:

for (var i = 0; i < $scope.reasonList.length; i++) 
    (function(i)
        $scope.rmaHasDefectdesc.rmaHasDefectdescPK.defectdescDefectdescId = $scope.reasonList[i].defectdescId;
        $scope.rmaHasDefectdesc.rmaHasDefectdescPK.returnreasonId = $scope.reasonList[i].returnreasonReturnreasonId.returnreasonId;
        $scope.rmaHasDefectdesc.rmaHasDefectdescPK.rmaId = rmaId;
        savedRmaHasDefectdesc = rmaDefectSvc.save(, $scope.rmaHasDefectdesc);
        savedRmaHasDefectdesc.$promise.then(function (response) 
            $scope.savedRmaHasDefectdesc = response;
            console.log('i: ' + i)
            console.log('defectdescDefectdescId:' + response.rmaHasDefectdescPK.defectdescDefectdescId);
            console.log('returnreasonId:' + response.rmaHasDefectdescPK.returnreasonId);
            console.log('rmaId:' + response.rmaHasDefectdescPK.rmaId);
        , function (error) 
            alert('Error in saving reasons' + error);
        );
    )(i)
 // For loop ending

其他人提到的问题是您的循环在承诺完成之前完成,因此当您在控制台登录时,i 已经更新。

【讨论】:

ReferenceError: i 未在 (i) 行中定义

以上是关于AngularJS 中的链式承诺的主要内容,如果未能解决你的问题,请参考以下文章

Angularjs 承诺拒绝链

AngularJS 承诺处理 CoffeeScript 类

使用 AngularJS 立即返回一个已解决的承诺

AngularJS:访问嵌套在 $scope 中的对象

AngularJS 资源承诺

AngularJS 测试 - 来自服务的承诺无法解决