Javascript AngularJS承诺挂UI
我的应用程序挂起,即使我正在使用承诺运行计算 我正在用英语写一个21点小游戏。在这个游戏中,我想在我的游戏板底部显示牌的排列。当我不调用计算排列的Javascript AngularJS承诺挂UI,javascript,angularjs,Javascript,Angularjs,我的应用程序挂起,即使我正在使用承诺运行计算 我正在用英语写一个21点小游戏。在这个游戏中,我想在我的游戏板底部显示牌的排列。当我不调用计算排列的getData()方法(见下文)时,我的游戏板渲染速度很快。但是当我调用getData()时,我的UI挂起 我声明并返回承诺的服务如下所示: app.service('cardService', ['$q', 'myservice', 'calculation', function ($q, myservice, calculation) {
getData()
方法(见下文)时,我的游戏板渲染速度很快。但是当我调用getData()
时,我的UI挂起
我声明并返回承诺的服务如下所示:
app.service('cardService', ['$q', 'myservice', 'calculation', function ($q, myservice, calculation) {
return {
getData: function () {
var defer = $q.defer();
myservice.setup_deck();
var cards = myservice.get_needed_cards(myservice.player_hand, myservice.static_deck);
// This is calculation-intensive
var dh_grouped = calculation.step1(cards);
var result = calculation.step2(dh_grouped);
defer.resolve(result);
return defer.promise;
}
};
}]);
// controller.js
$scope.display_calculations = function () {
cardService.getData().then(function(result){
$scope.calcs = result;
console.log('calculations successful');
});
console.log('this message shows before the one above');
};
// The relevant HTML
<td ng-repeat="c in calcs">{{c.result}}</td>
现在,我用一种非常普通的方式称之为承诺:
app.service('cardService', ['$q', 'myservice', 'calculation', function ($q, myservice, calculation) {
return {
getData: function () {
var defer = $q.defer();
myservice.setup_deck();
var cards = myservice.get_needed_cards(myservice.player_hand, myservice.static_deck);
// This is calculation-intensive
var dh_grouped = calculation.step1(cards);
var result = calculation.step2(dh_grouped);
defer.resolve(result);
return defer.promise;
}
};
}]);
// controller.js
$scope.display_calculations = function () {
cardService.getData().then(function(result){
$scope.calcs = result;
console.log('calculations successful');
});
console.log('this message shows before the one above');
};
// The relevant HTML
<td ng-repeat="c in calcs">{{c.result}}</td>
上述方法不起作用。我的UI仍然挂起防止UI挂起的唯一方法是不调用getData()
我如何使用angular,使我昂贵的操作不会挂起UI
另外,我正在使用Angular 1.2.21,甚至尝试使用1.5.x,但也不起作用。使用$timeout
app.service('cardService', ['$q', '$timeout', 'myservice', 'calculation', function ($q, $timeout, myservice, calculation) {
return {
getData: function () {
return $timeout(function() {
myservice.setup_deck();
var cards = myservice.get_needed_cards(myservice.player_hand, myservice.static_deck);
// This is calculation-intensive
var dh_grouped = calculation.step1(cards);
return calculation.step2(dh_grouped);
}, 1);
}
};
}]);
这将推迟执行并让您的UI先加载$timeout
返回一个承诺,以便代码的其余部分可以保持不变。使用$timeout
app.service('cardService', ['$q', '$timeout', 'myservice', 'calculation', function ($q, $timeout, myservice, calculation) {
return {
getData: function () {
return $timeout(function() {
myservice.setup_deck();
var cards = myservice.get_needed_cards(myservice.player_hand, myservice.static_deck);
// This is calculation-intensive
var dh_grouped = calculation.step1(cards);
return calculation.step2(dh_grouped);
}, 1);
}
};
}]);
这将推迟执行并让您的UI先加载
$timeout
返回一个承诺,以便代码的其余部分保持不变。您可能会将承诺与线程混淆。承诺不支持并发执行。如果需要在JavaScript中执行CPU密集型任务,同时保持UI响应,则必须:
- (浏览器)
- (Node.js)
- 找到一种方法将计算分成小块,并逐块运行(这样UI可以在每个块之间响应用户)
- (浏览器)
- (Node.js)
- 找到一种方法将计算分成小块,并逐块运行(这样UI可以在每个块之间响应用户)
- 您可能会将承诺与线程混淆。承诺不支持并发执行。如果需要在JavaScript中执行CPU密集型任务,同时保持UI响应,则必须:
var myApp = angular.module('myApp',['ngRoute']);
服务
var yourServiceModule = myApp.service('YourService', function ($http) {
this.your_method = function (a) { return a*a};
});
控制器
//just wrap your service,http call using $timeout
$timeout(function() {
//vanilla service call
YourService.your_method().then(
function (response) {
//console.log("sync_with_cloud: "+ response);
$scope.check_cloud_port_statuses_progress=100;
//...
},
function(data) {
// Handle error here
$rootScope.global_config_1 += "\nError(333): cant connect to cloud at "+Date.now();+"\n\n";
$scope.check_cloud_port_statuses_progress = -1;
}
);
}, 8);
我当时在一个嵌入式系统上工作,根本没有GUI刷新问题,但我时不时地挂断(这是一个物理设备,所以它会保持开启状态达数天/数月/数年),因为@DerekMT12提到添加$timeout修复了此行为 模块
var myApp = angular.module('myApp',['ngRoute']);
服务
var yourServiceModule = myApp.service('YourService', function ($http) {
this.your_method = function (a) { return a*a};
});
控制器
//just wrap your service,http call using $timeout
$timeout(function() {
//vanilla service call
YourService.your_method().then(
function (response) {
//console.log("sync_with_cloud: "+ response);
$scope.check_cloud_port_statuses_progress=100;
//...
},
function(data) {
// Handle error here
$rootScope.global_config_1 += "\nError(333): cant connect to cloud at "+Date.now();+"\n\n";
$scope.check_cloud_port_statuses_progress = -1;
}
);
}, 8);
这将让UI先加载,然后挂起。也许对OP来说已经足够了。是的,它最终会运行。唯一要做的另一件事就是优化这个缓慢的方法。它成功了!在计算并返回结果之前,我的电路板显示,没有任何内容挂起。非常感谢。这将让UI先加载,然后挂起。也许对OP来说已经足够了。是的,它最终会运行。唯一要做的另一件事就是优化这个缓慢的方法。它成功了!在计算并返回结果之前,我的电路板显示,没有任何内容挂起。非常感谢。在哪里以及多久调用一次显示_计算?如果UI仅在一次调用中挂起,那么问题与Angular无关,而是与常规JS有关。昂贵的计算要么异步进行,要么移动到web worker以不阻塞主线程。是的,所以我使用$timeout,它按照下面的DerekMT回答工作,我的问题得到了解决。在哪里调用display_计算,以及调用display_计算的频率如何?如果UI仅在一次调用中挂起,那么问题与Angular无关,而是与常规JS有关。昂贵的计算要么异步进行,要么移动到web worker以不阻塞主线程。是的,所以我使用$timeout,它按照下面的DerekMT回答工作,我的问题得到了解决。谢谢!我会调查的。在这种情况下,使用DerekMT建议的$timeout对我很有效。谢谢!我会调查的。在这种情况下,使用DerekMT建议的$timeout对我很有效。