javascript - 当服务中存在嵌套的 promise 关系时,AngularJS 表现异常

标签 javascript angularjs

我有 2 个 plunkr 准备好展示我的困惑。我正在寻求一个明确的解释,以准确说明为什么第一个 plunkr 失败,而第二个 plunkr 有效。

在第一个 plunkr 中,我模拟调用外部库来执行某种网络身份验证。问题是,当来自原始 Controller 级别方法的链中有 2 个 promise 时,传递给第一个 promise 以在 resolve 时执行的函数永远不会触发,并且尽管解决了每个 promise,也不会触发链中更远的任何其他 promise。

http://plnkr.co/edit/6uKnVvEI3bJvfmaUoWN0

但是,当我将调用更改为使用 $timeout 时,无论它是用于模拟延迟,还是只是包装从实际外部操作返回的 deferred.resolve(例如调用 REST API) ,一切都按预期工作。在第二个 plunkr 中,您可以看到登录功能在两个 deferred.resolve 调用都被修改为包含在 $timeout 调用中后工作得很好。

此外,我还包含了一个测试用例,其他人建议将其作为在返回 promise 之前解决 promise 失败的问题。这显然不是这种情况,因为第二个 plunkr 在这样做时工作得很好。请注意,此替代方法不使用 $timeout 但仍然可以正常工作。这向我表明,当两个服务(testApi、authService)都返回 promise 对象时,这两个服务(testApi、authService)之间的关系有一些特殊之处,导致必须向上解析的嵌套 promise 链。

http://plnkr.co/edit/xp8NeZKWDep6cPys5gJu?p=preview

有谁能向我解释为什么这些 promise 在一个实例中失败,但在另一个实例中没有嵌套,或者嵌套在 $timeout 中时有效?

我的直觉与摘要周期有关,但我无法理解为什么摘要周期会影响本质上独立于 Controller 运行的服务。它们不是 $scope 上需要在 Controller 加载之前解析的属性,而是包装返回 promise 的服务调用的函数。

最佳答案

你的预感是对的。当你使用 setTimeout 时,它会触发一个 Angular 一无所知的事件;如果您改用 $timeout 则情况并非如此。因此,为了让您的第一个 Plunker 脚本起作用,您需要通过调用 $rootScope.$apply() 手动启动摘要循环:

angular.module('testApi', []).factory('testApi', function($q, $rootScope) {
...    
    setTimeout(function() { 
        $rootScope.$apply(function() { 
            deferred.resolve({user: { id: '1', name: 'bozo'}}); 
        });
    }, 1000);

笨蛋 here .

如果您坚持使用 $timeout,则无需执行上述任何操作,我建议您这样做。

SO question有更多关于为什么只在进入 $digest 周期时才调用 promises 回调的信息。

关于javascript - 当服务中存在嵌套的 promise 关系时,AngularJS 表现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18755383/

相关文章:

javascript - 使用 Javascript 禁用 HTML 表单中的字段取决于从下拉列表中选择的值

javascript - jQuery 数据选择器中正则表达式的性能 : dependance on certain string length

Javascript 的安排使得没有 Javascript 时一切都正常?

javascript - 使用 ng-click 和 ng-repeat 使表格单元格处于事件状态

javascript - 如何在嵌套的 ng-repeat 指令中使用控制语句(if 语句)?

javascript - 使用包含某些查询字符串参数的 src 创建图像元素

javascript - 创建一个更改不同元素的背景和文本颜色的按钮

javascript - Angular JS 过滤器或语句

angularjs - 将youtube视频嵌入到iFrame中

javascript - 如何在 Angular http请求的错误和成功回调之间共享变量