什么是apply now

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是apply now相关的知识,希望对你有一定的参考价值。

我下了个全英文版的小红伞啊,杀毒软件,但愿有牛人很会用这个软件啊,
杀到特洛伊病毒的时候,会弹出一个小框,显示病毒,
然后底下会有“APPLY NOW”和“CANCLE”(好像是cancle光顾着注意apply去了~唉~我这脑子~)
然后问题就是APPLY NOW到底是什么意思呢?网上查了一下,本意确实是“立即申请”但是这个用在病毒上好像有点牛头不对马嘴啊~~唉~~
知情人士速告之于吾~

APPLY NOW = 立刻执行,意为立刻杀灭相关病毒。

CANCEL = 取消,不采取任何动作。
参考技术A apply有多种意思,此处应该翻译为“应用”。
可能需要你选择一除操作,比如“清除病毒”或者“删除文件”,然后应用其中一项。

什么时候使用 $scope.$apply() 是安全的?

【中文标题】什么时候使用 $scope.$apply() 是安全的?【英文标题】:When is it safe to use $scope.$apply()? 【发布时间】:2015-07-01 06:21:14 【问题描述】:

我想标题很清楚我在问什么。我创建了这个小提琴:http://jsfiddle.net/Sourabh_/HB7LU/13142/

在小提琴中,我尝试复制async 场景。这只是一个示例,但在 AJAX 调用中,如果我不使用 $scope.$apply(),则列表不会更新。我想知道每次我进行 AJAX 调用以更新列表时使用 $scope.$apply() 是否安全,或者我可以使用其他一些机制吗?

我为复制场景而编写的代码(与小提琴相同):

HTML

<div ng-controller="MyCtrl">
  <li ng-repeat="item in items">
    item.name
  </li>
  <button ng-click="change()">Change</button>
</div>

JS

var myApp = angular.module('myApp',[]);

function MyCtrl($scope) 
  $scope.items = [name : "abc",name : "xyz",name : "cde"];

  $scope.change = function()
    test(function(testItem)
      $scope.items = testItem;
      //$scope.$apply();
    )
  
  function test(callback)
    var testItem = [
                    name : "mno",
                    name : "pqr",
                    name :   "ste"
                   ];
    setTimeout(function()callback(testItem),2000);
  

【问题讨论】:

您是否在尝试模仿 REST 调用?如果是这样: $http 请求返回一个承诺,您可以在控制器内部使用 .then() 来更改范围。不要在 REST 调用中设置新的范围和 $apply()。因为,你现在的所作所为毫无意义。 我知道它现在无济于事,但 Angular 2.0 将解决这个可怕的问题。 每次范围更改都贯穿摘要。 API 调用中的超时对我来说很臭。如果服务器需要更多时间怎么办?如果它被调用 2 或 3 次怎么办? @gruberb。那么在什么场景下我们使用apply(),有没有只有apply()才起作用的情况呢?或者换句话说,我们什么时候应该使用 apply()? 我认为当你觉得需要 apply() 时,可以做得更好。作为 $rootScope,$apply() 应该在极少数情况下使用。 github.com/angular/angular.js/wiki/… 【参考方案1】:

编辑不清楚 OP 是否试图模拟后端调用。即便如此,使用 $timeout 服务是避免手动调用 $scope.$apply 的好方法,并且是比使用 Promise 更普遍适用的解决方案(如果你不调用 $http 它不会'通过用 Promise 包装它们来强制你的更改进入下一个周期总是有意义的)。


更新您的代码以使用$timeout service,它应该可以工作而无需调用$apply

$timeout 是原生 setTimeout 的包装器,但有一个重要区别:$timeout 将至少延迟执行,直到下一个 $digest 循环运行。

所以没有延迟传递仍然会将执行延迟到下一个周期。传入 2000 会将执行延迟到 2000ms 后的下一个周期。

因此,这是一个简单的技巧,可以确保您的更改被 Angular 接收,而无需手动调用 $apply(在任何情况下都被认为是不安全的)

function MyCtrl($scope, $timeout) 
  $scope.items = [name : "abc",name : "xyz",name : "cde"];

  $scope.change = function()
    test(function(testItem)
      $scope.items = testItem;
      //$scope.$apply();
    )
  
  function test(callback)
    var testItem = [
                    name : "mno",
                    name : "pqr",
                    name :   "ste"
                   ];
    $timeout(function()callback(testItem),2000);
  

【讨论】:

我认为这个人想要模仿 REST 调用,建议只使用带有 .success()、.then() 或 .error() 的 promise 而不是超时。跨度> 这在问题中并不明显。 OP 询问何时可以安全地使用 $apply,但从来没有,所以我提供了一个替代方案。使用 $q 当然也可以解决这个问题,但使用 $timeout 是一种更简单的方法,可以将您的更改强制进入下一个周期。 @Anzeo。抱歉,如果我不清楚,但是“测试”功能只是模仿服务器,其中回调实际上是来自服务器的响应。 +1 替代方案。 如果你不使用 $http 进行异步调用,这个解决方案仍然比手动调用 $scope.$apply 更受欢迎【参考方案2】:

如果您想模拟 API-Rest-Call,请在您的 Controller 中使用返回的 promise,而不是在 Rest-Call 中设置范围。

$http.get('uri')
  .success(function(data) 
    $scope.items = data
);

避免使用$apply()。 From the Angular GitHub Repo:

$scope.$apply() 应该尽可能靠近异步事件绑定发生 可能。

不要在你的代码中随意使用它。如果你这样做 (!$scope.$$phase) $scope.$apply()是因为你不够高 在调用堆栈中。

你的问题:

如果您发现自己需要 $apply(),请重新考虑您的结构。 出于安全原因:切勿使用$apply()

【讨论】:

使用 $apply() 并不安全是不正确的。我们不能 $apply()。无论如何,它都会在应用程序的生命周期中发生。在适当的时候使用和理解它是非常重要的。正确的是,尽可能不要调用 $apply(),即 $timeout 而不是 setTimeout,... 我能想到不使用 $apply() 的唯一原因是当您只想使用 $digest() 时。因为 digest 只是评估当前范围的变量,但 $apply() 最终调用 $rootScope.$digest() 重新计算所有绑定,这是非常昂贵的。但是,如果用例是这样,那么我认为使用 ti 没有什么问题【参考方案3】:

每次使用非“角度方式”的东西时都需要使用 $apply,就像 Anzeo 所说的 $timeout。 例如,如果您使用 jQuery 的 http 而不是 angular 的 $http,则必须添加 $scope.$apply。

【讨论】:

【参考方案4】:

$apply,应在代码未在角度摘要循环中执行时使用。在正常情况下,我们不需要使用它,但如果我们有一个从 jQuery 事件处理程序或像 setTimeout() 这样的方法调用的代码,我们可能必须使用它。即使您有一个从另一个角度函数(如 watch 或角度事件处理程序)调用的函数,您也不需要使用 $apply(),因为这些脚本是在摘要循环中执行的。

一种安全的方法是在调用$scope.$apply() 之前检查$scope.$$phase 参数

if($scope.$$phase)
    $scope.$apply();

在您的情况下,您可以按照另一个答案中的建议使用 $timeout

What is $$phase in AngularJS? Why is using if(!$scope.$$phase) $scope.$apply() an anti-pattern?

【讨论】:

【参考方案5】:

以上所有答案都提供了一些信息,但他们没有回答我的一些疑问,或者至少我不明白。所以我给我自己的。

角度文档when to use $apply中非常清楚地说明了

$http 或 $timeout 或 ng-click, ng-..... 的回调包含 $apply() 。因此,当人们说你在做有角度的做事时不必使用 $apply() 时,就是这样。但是,其中一个答案提到角度事件处理程序也用 $apply() 包装。这不是真的,或者用户的意思只是 ng-click 类型的事件(同样是 ng-....)。如果事件在 $http 或 $timeout 或 ng-click 之外的 rootScope(或任何范围)上广播,例如:来自自定义服务,那么您需要在您的范围上使用 $apply() 尽管 $rootScope .$broadcast 也是有角度的做事方式。在大多数情况下,我们不需要这个,因为当事情发生时应用程序的状态会改变。即,点击,选择更改等......当我们分别使用 ng-click ng-change 时,这些在角度方面已经在使用 $apply() 。使用 signalr 或 socket.io 处理服务器端事件,并在编写自定义指令时,只需要更改指令的范围是少数几个使用 $apply() 非常重要的例子

【讨论】:

【参考方案6】:

正如@gruberb 在 cmets 中指出的那样,如果您尝试模拟 REST 调用,最好使用 Promise,而不是 $apply

为此,您需要使用$q service 创建并返回一个promise。然后只需调用它并通过在返回的 Promise 上调用 then() 方法来处理您的结果。

function MyCtrl($scope, $q) 
    $scope.items = [name : "abc",name : "xyz",name : "cde"];

    $scope.change = function()

        test().then(function (items) 
            $scope.items = items;
            $scope.$apply();
        );
    ;

    function test() 
        var defered = $q.defer();

        var testItem = [
            name : "mno",
            name : "pqr",
            name :   "ste"
        ];

        setTimeout(function() 
            defered.resolve(testItem);
        ,2000);

        return defered.promise;
    

【讨论】:

【参考方案7】:

更好的方法是使用$scope.$applyAsync(); 而不是$scope.$apply();

这里给出了避免使用 $scope.$apply() 的原因:

Error: [$rootScope:inprog] digest in progress. Fix

【讨论】:

一个理由如果写在这里会更有用。链接有时会停止响应。

以上是关于什么是apply now的主要内容,如果未能解决你的问题,请参考以下文章

call和apply区别是什么,哪个性能更好一些?

js中的apply,call,arguments,callee,caller详解

jquery 中 fn.apply(this, arguments)是什么函数?有什么作用?能举个例子吗

$.when.apply($, someArray) 做啥?

js apply的用法

关于JS中apply和call详细解答