Angular然后不会触发递归函数的Promise

时间:2016-09-21 18:08:57

标签: javascript angularjs recursion

就在我以为我有承诺的时候,我再次难过了。我试图使用递归函数来返回一个promise。它看起来像是在工作但是"然后"部分从未被击中。我尝试使用$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,但是&#34;然后&#34;永远不会开火。

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:1)

在解析或拒绝之前,必须由函数返回promise。

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对象上实现。因此,当函数返回promise时,然后才能正常工作。

您可以查看此示例https://jsbin.com/daseyu/edit?html,js,console,output 它工作正常。

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

希望这有帮助。

答案 1 :(得分:1)

getClusterLink被调用的情况下,您的contractorService.gethyperlink函数不会返回承诺。我不知道你不能从中得到例外。即使您总是返回deferred.promise,也不会在该分支中解析。

但你不应该在这里使用延迟。 Just use $q.resolve,并链接到$http承诺gethyperlink返回。请注意,.success已被弃用,并且没有像then这样的链接 - return来自该回调是没有意义的。

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();
    }
}

答案 2 :(得分:1)

我明白了。似乎问题是我在递归函数中有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;

};