简体   繁体   English

Angular然后不会触发对递归函数的承诺

[英]Angular Then doesn't trigger for Promise on Recursive Function

Just when I thought I had promises figured out, I'm stumped again. 就在我以为自己实现了诺言的时候,我再次陷入了困境。 I am trying to use a recursive function to return a promise. 我正在尝试使用递归函数来返回承诺。 It looks like it is working but the "then" portion never gets hit. 看起来它正在运行,但“ then”部分再也不会受到打击。 I tried using $q.all but that is causing me a problem with multiple calls to my Web API. 我尝试使用$q.all但这导致我多次调用Web API时出现问题。 Rewriting the code to use recursion seemed like the answer, but I cannot get the "then" to execute. 重写代码以使用递归似乎是答案,但是我无法执行“ then”。 I figure that I must be missing something simple but I can't seem to figure out just what. 我认为我必须缺少一些简单的东西,但是我似乎无法弄清楚到底是什么。

Here is the call to the function: 这是该函数的调用:

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

                    })

Here is the recursive function: 这是递归函数:

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

The function itself works correctly. 该函数本身正常工作。 It hits the resolve and the return deferred.promise , but the "then" never fires. 它实现了resolvereturn deferred.promise ,但是“ then”永不触发。

Any assistance is greatly appreciated! 非常感谢您的协助!

promise has to be returned by the function before resolve or rejecting it. 在解决或拒绝它之前,该函数必须返回诺言。

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

.then is implemented on promise object. .then在promise对象上实现。 So as the function is returning the promise ,.then would work fine. 因此,当函数返回promise时,.n就可以正常工作。

You can look at this sample https://jsbin.com/daseyu/edit?html,js,console,output It works fine. 您可以查看此示例https://jsbin.com/daseyu/edit?html,js,console,output效果很好。

I think the problem is because you are returning getClusterLink in success. 我认为问题是因为您成功返回了getClusterLink。 You can return in end of if loop and not in .success. 您可以在if循环的结尾而不是.success中返回。

Hope this helps. 希望这可以帮助。

Your getClusterLink function does not return a promise in the case where contractorService.gethyperlink is called. 在调用contractorService.gethyperlink的情况下,您的getClusterLink函数不会返回promise。 I wonder you don't get an exception from that. 我想您不会从中得到例外。 And even if you always returned deferred.promise , it wouldn't be resolved in that branch. 即使您始终返回deferred.promise ,也不会在该分支中对其进行解析。

But you should not use a deferred at all here. 但是您不应该在这里使用所有递延的内容。 Just use $q.resolve , and chain onto the $http promise that gethyperlink returns. 只需使用$q.resolve ,并链接到gethyperlink返回的$http承诺上gethyperlink Notice that .success is deprecated, and does no chaining like then does - return ing from that callback is pointless. 请注意,不赞成使用.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();
    }
}

I figured it out. 我想到了。 Seems the problem was that I had var deferred = $q.defer() inside of the recursive function so it kept resetting the variable. 似乎问题出在递归函数内部,我有var deferred = $q.defer() ,所以它一直在重置变量。 Moving it outside of the function (like below) resolved the issue and the "then" now fires. 将其移出函数(如下所示)可以解决问题,然后触发“ 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;

};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM