gpt4 book ai didi

angularjs - 为什么使用 if(!$scope.$$phase) $scope.$apply() 是反模式?

转载 作者:行者123 更新时间:2023-12-03 04:59:51 24 4
gpt4 key购买 nike

有时我需要在代码中使用$scope.$apply,有时它会抛出“摘要已在进行中”错误。所以我开始寻找解决这个问题的方法并发现了这个问题:AngularJS : Prevent error $digest already in progress when calling $scope.$apply() 。但是,在评论中(以及 Angular wiki 上),您可以阅读:

Don't do if (!$scope.$$phase) $scope.$apply(), it means your $scope.$apply() isn't high enough in the call stack.

现在我有两个问题:

  1. 为什么这是一种反模式?
  2. 如何安全使用 $scope.$apply?

防止“摘要已在进行中”错误的另一个“解决方案”似乎是使用 $timeout:

$timeout(function() {
//...
});

这是要走的路吗?更安全吗?因此,真正的问题是:我如何完全消除“摘要已在进行中”错误的可能性?

PS:我只在不同步的非 angularjs 回调中使用 $scope.$apply 。 (据我所知,如果您希望应用更改,则必须使用 $scope.$apply )

最佳答案

经过更多的挖掘,我能够解决使用$scope.$apply是否总是安全的问题。简短的回答是肯定的。

长答案:

由于浏览器执行 JavaScript 的方式不同,两个摘要调用不可能偶然发生冲突。

The JavaScript code we write doesn’t all run in one go, instead it executes in turns. Each of these turns runs uninterupted from start to finish, and when a turn is running, nothing else happens in our browser. (from http://jimhoskins.com/2012/12/17/angularjs-and-apply.html)

因此错误“digest已经在进行中”只能在一种情况下发生:当一个$apply在另一个$apply中发出时,例如:

$scope.apply(function() {
// some code...
$scope.apply(function() { ... });
});

如果我们在纯非 angularjs 回调中使用 $scope.apply,例如 setTimeout 的回调,则不会出现这种情况。 >。因此,以下代码是 100% 防弹的,不需要需要执行 if (!$scope.$$phase) $scope.$apply()

setTimeout(function () {
$scope.$apply(function () {
$scope.message = "Timeout called!";
});
}, 2000);

即使这个也是安全的:

$scope.$apply(function () {
setTimeout(function () {
$scope.$apply(function () {
$scope.message = "Timeout called!";
});
}, 2000);
});

什么是安全的(因为 $timeout - 像所有 angularjs 助手一样 - 已经为你调用了 $scope.$apply ):

$timeout(function () {
$scope.$apply(function () {
$scope.message = "Timeout called!";
});
}, 2000);

这也解释了为什么使用 if (!$scope.$$phase) $scope.$apply() 是一种反模式。如果您以正确的方式使用 $scope.$apply ,则根本不需要它:例如在 setTimeout 等纯 js 回调中。

阅读http://jimhoskins.com/2012/12/17/angularjs-and-apply.html更详细的解释。

关于angularjs - 为什么使用 if(!$scope.$$phase) $scope.$apply() 是反模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22346990/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com