2016-09-21 65 views
0

就在我以为我已经承诺想通了,我又难住了。我正在尝试使用递归函数来返回一个承诺。它看起来像在工作,但“那么”部分永远不会被击中。我试过使用$q.all,但是这对我的Web API多次调用造成了问题。重写代码以使用递归看起来就像是答案,但我无法得到“然后”执行。我认为我必须错过简单的东西,但我似乎无法弄清楚什么。角那么对于承诺不会触发递归函数

这里是调用该函数:

    getClusterLink(linkcodes, returnString) 
        .then(function() { 
         value.vchTextBeforeQuestionCluster = $scope.returnString; 

        }) 

下面是递归函数:

function getClusterLink(linkcodes, returnString) { 
    var deferred = $q.defer(); 
    $scope.returnString = returnString; 
    if (linkcount < linkcodes.length) { 
     contractorService.gethyperlink(linkcodes[linkcount]) 
     .success(function (data) { 
      var vchUrl = data[0].vchUrl; 
      var end = vchUrl.length; 
      var docID = vchUrl.substring(vchUrl.indexOf("=") + 1, end); 
      var vchLinkName = data[0].vchLinkName; 
      var yay = '<a href="" ng-click="getDocumentByID(' + docID + ')">' + vchLinkName + '</a>'; 
      var yCode = "|Y" + linkcodes[linkcount] + "~"; 
      $scope.returnString = $scope.returnString.replaceAll(yCode, yay); 
      linkcount++; 

      return getClusterLink(linkcodes, $scope.returnString); 
     }) 

    } 
    else { 
     deferred.resolve(); 
     return deferred.promise; 
    } 
}; 

函数本身工作正常。它击中了resolvereturn deferred.promise,但是“那么”从未激发。

任何援助非常感谢!

+1

你不会在条件的第一个分支中返回任何东西...惊讶你没有得到一个类型错误。 –

+0

我会的。我返回该功能。 –

+0

只有'返回'我看到在该分支*是在回调* –

回答

0

我想通了。似乎问题是我在递归函数内有var deferred = $q.defer(),所以它保持重置变量。将它移动到函数之外(如下所示)解决了问题,“then”现在会触发。

var thisdeferred = $q.defer(); 

function getClusterLink(linkcodes, returnString) { 

    if (linkcount < linkcodes.length) { 
     contractorService.gethyperlink(linkcodes[linkcount]) 
     .success(function (data) { 
      var vchUrl = data[0].vchUrl; 
      var end = vchUrl.length; 
      var docID = vchUrl.substring(vchUrl.indexOf("=") + 1, end); 
      var vchLinkName = data[0].vchLinkName; 
      var yay = '<a href="" ng-click="getDocumentByID(' + docID + ')">' + vchLinkName + '</a>'; 
      var yCode = "|Y" + linkcodes[linkcount] + "~"; 
      $scope.returnString = $scope.returnString.replaceAll(yCode, yay); 
      linkcount++; 
      return getClusterLink(linkcodes, $scope.returnString); 
     }) 


    } 
    else { 
     thisdeferred.resolve(); 
    } 
    return thisdeferred.promise; 

}; 
1

承诺必须由函数解析之前或拒绝其返回。

function getClusterLink(linkcodes, returnString) { 
var deferred = $q.defer(); 
$scope.returnString = returnString; 
if (linkcount < linkcodes.length) { 
    contractorService.gethyperlink(linkcodes[linkcount]) 
    .success(function (data) { 
     var vchUrl = data[0].vchUrl; 
     var end = vchUrl.length; 
     var docID = vchUrl.substring(vchUrl.indexOf("=") + 1, end); 
     var vchLinkName = data[0].vchLinkName; 
     var yay = '<a href="" ng-click="getDocumentByID(' + docID + ')">' + vchLinkName + '</a>'; 
     var yCode = "|Y" + linkcodes[linkcount] + "~"; 
     $scope.returnString = $scope.returnString.replaceAll(yCode, yay); 
     linkcount++; 


    }) 
return getClusterLink(linkcodes, $scope.returnString); 
} 
else { 
    deferred.resolve(); 
} 
return deferred.promise; 
}; 

。然后在promise对象上实现。所以随着函数返回的承诺,。然后将正常工作。

你可以看一下这个样本https://jsbin.com/daseyu/edit?html,js,console,output 它工作正常。

我认为这个问题是因为你在成功返回getClusterLink。您可以在if循环结束时返回,而不是在.success中返回。

希望这会有所帮助。

+0

先试了一下,它不起作用,而且通过放在if语句之外,不管怎样,它都会一遍又一遍地返回诺言。 –

+0

@RaniRadcliff我已经更新了我的答案。 – vbharath

+0

感谢您的帮助。我没有投你的答案,它确实帮了我。 –

1

getClusterLink功能不会在contractorService.gethyperlink被称为情况下返回一个承诺。我不知道你从中得不到例外。即使你总是返回deferred.promise,它也不会在该分支中解决。

但你不应该使用在延迟都在这里。 Just use $q.resolve,并链接到$http承诺gethyperlink返回。请注意,.success已弃用,并且没有链接,如then确实 - return ing从该回调是毫无意义的。

function getClusterLink(linkcodes, returnString) { 
    $scope.returnString = returnString; 
    if (linkcount < linkcodes.length) { 
     return contractorService.gethyperlink(linkcodes[linkcount]) 
//  ^^^^^^ 
     .then(function (data) { 
//  ^^^^^ 
      var vchUrl = data[0].vchUrl; 
      var end = vchUrl.length; 
      var docID = vchUrl.substring(vchUrl.indexOf("=") + 1, end); 
      var vchLinkName = data[0].vchLinkName; 
      var yay = '<a href="" ng-click="getDocumentByID(' + docID + ')">' + vchLinkName + '</a>'; 
      var yCode = "|Y" + linkcodes[linkcount] + "~"; 
      $scope.returnString = $scope.returnString.replaceAll(yCode, yay); 
      linkcount++; 

      return getClusterLink(linkcodes, $scope.returnString); 
     }); 
    } else { 
     return $q.resolve(); 
    } 
}