【问题标题】:Angular Then doesn't trigger for Promise on Recursive FunctionAngular Then 不会触发 Promise on Recursive Function
【发布时间】:2017-01-30 02:58:09
【问题描述】:

就在我以为我已经完成了承诺的时候,我又被难住了。我正在尝试使用递归函数来返回一个承诺。看起来它正在工作,但“then”部分永远不会被击中。我尝试使用$q.all,但这导致我多次调用我的 Web API 时出现问题。重写代码以使用递归似乎是答案,但我无法让“then”执行。我想我一定错过了一些简单的东西,但我似乎无法弄清楚到底是什么。

这是对函数的调用:

                    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,但“then”永远不会触发。

非常感谢任何帮助!

【问题讨论】:

  • 您没有在条件的第一个分支中返回任何内容......很惊讶您没有收到类型错误。
  • 我愿意。我返回函数。
  • 只有return 我在那个分支中看到在回调中
  • if中有return,else中有return。
  • @JaredSmith 是正确的。您的递归逻辑是正确的,因此它正在工作。但是,由于getClusterLink 在第一个“if”块中没有返回任何内容,因此承诺链被破坏了。 return getClusterLink(... 与成功回调中的匿名函数相关。如果contractorService.gethyperlink服务方法也是一个promise;也许尝试退货?:return contractorService.gethyperlink.

标签: javascript angularjs recursion


【解决方案1】:

promise 必须在 resolve 或拒绝它之前由函数返回。

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 在 promise 对象上实现。因此,当函数返回 promise 时,.then 可以正常工作。

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

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

希望这会有所帮助。

【讨论】:

  • 先试过了。它不起作用。此外,通过放在 if 语句之外,无论如何它都会一遍又一遍地返回承诺。
  • 感谢您的帮助。请注意,我没有否决您的回答。它确实帮助了我。
【解决方案2】:

在调用contractorService.gethyperlink 的情况下,您的getClusterLink 函数不会返回承诺。我想知道你没有得到例外。即使你总是返回deferred.promise,它也不会在那个分支中得到解决。

但是你不应该在这里使用 deferred。 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();
    }
}

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2017-06-08
      • 1970-01-01
      • 1970-01-01
      • 2020-12-27
      • 2019-01-12
      • 1970-01-01
      • 1970-01-01
      • 2015-11-20
      • 1970-01-01
      相关资源
      最近更新 更多