我在服务中有一个函数需要很长时间才能计算,所以我想在范围上显示一条消息来显示它的计算结果。 我在这里创建了一个(简化的)jsfiddle:http://jsfiddle.net/rikboeykens/brwfw3g9/
var app = angular.module('myApp', []);
app.service('testService', function(){
this.longFunction=function(){
for (var i=0; i<1000000000;i++){
}
}
});
function TestCtrl($scope, testService)
{
$scope.$apply(function(){$scope.waiting="not waiting";});
$scope.longFunction = function(){
$scope.waiting="waiting";
testService.longFunction();
$scope.waiting="not waiting";
}
}
testService上的longFunction大约需要两秒钟才能完成,但$ scope.waiting在发生这种情况时不会更新为“等待”。
我尝试使用$ scope。$ apply然后我得到一个错误,说$ apply已经在进行中。
如果我在testService上异步执行longFunction,它会起作用吗?我一直在研究使用promises,但我不确定如何实现它们。
答案 0 :(得分:2)
您可以使用$timeout
。
function TestCtrl($scope, testService, $timeout)
{
$scope.waiting="not waiting";
$scope.longFunction = function(){
$scope.waiting="waiting";
$timeout(function(){
testService.longFunction();
$scope.waiting="not waiting";
})
}
}
答案 1 :(得分:1)
它正常工作,但您没有看到waiting
消息,因为longFunction
同步运行,我怀疑它的执行会阻止UI被绘制以显示waiting
消息更新。当longFunction
调用结束时,UI线程不忙,并设置"not waiting"
消息,使您无法阅读"waiting
“文本。
这是Web浏览器中的预期行为,因为所有内容都在UI线程中执行,如果操作是同步的并且UI被冻结了一段时间,则没有Web浏览器可以优先处理工作。由于长for
循环或长计算会占用大量CPU资源,因此Web浏览器需要等到操作结束才能继续绘制屏幕。
您可以在Angular中使用setTimeout
flavor来模拟异步操作,这将优先使用UI,您将能够看到消息更改:
$scope.longFunction = function(){
$scope.waiting="waiting";
// Actually this is a workaround, because JS doesn't provide
// an elegant way of enqueueing asynchronous operations in the UI
// layer. BTW, does Web Workers mean something for you? ;)
$timeout(function() {
testService.longFunction();
}, 0);
$scope.waiting="not waiting";
}
答案 2 :(得分:1)
你肯定要超时执行服务功能。我在Codeopen.io上创建并编写了示例:http://codepen.io/skymk/pen/EjNpKL?editors=101
app.controller('Controller', ['$scope', 'testService', '$timeout', function($scope, testService, $timeout) {
$scope.waiting="not waiting";
$scope.longFunction = function() {
$scope.waiting="waiting";
$timeout(function() {
testService.longFunction();
$scope.waiting="not waiting";
}, 0);
}
$scope.longFunction()
}])