Angular应用程序中是否存在计算繁重任务的模式? (除了使用$ timeout以及延迟0来让他们离开调用堆栈?)即使使用$ timeout似乎也会在处理器本身启动时使UI无响应。我是否需要查看Web Workers或类似的东西那,还是有“Angular方式?”
答案 0 :(得分:2)
由于JavaScript是单线程的,因此您需要在服务器端执行计算,或者在处理之间执行超时(请参阅下划线' s defer()
,http://underscorejs.org/#defer)。否则,UI将不可避免地被阻止。
答案 1 :(得分:2)
我想出了一种方法来解决我的UI响应问题,方法是创建每次循环使用Angular $timeout
的特殊循环函数。
app.service('responsivenessService', function($q, $timeout) {
var self = this;
// Works like Underscore's map() except it uses setTimeout between each loop iteration
// to try to keep the UI as responsive as possible
self.responsiveMap = function(collection, evalFn)
{
var deferred = $q.defer();
// Closures to track the resulting collection as it's built and the iteration index
var resultCollection = [], index = 0;
function enQueueNext() {
$timeout(function () {
// Process the element at "index"
resultCollection.push(evalFn(collection[index]));
index++;
if (index < collection.length)
enQueueNext();
else
{
// We're done; resolve the promise
deferred.resolve(resultCollection);
}
}, 0);
}
// Start off the process
enQueueNext();
return deferred.promise;
}
return self;
});
此映射函数返回一个可分配给$scope
的promise。用法类似于Underscore中的map()
函数或较新浏览器中的本机Javascript数组:
$scope.results = responsivenessService.responsiveMap(initialdata, function() {
// Long-running or computationally intense code here
return result;
});
最初阻止整个UI的代码现在似乎在后台运行(虽然基本上它是一种幻觉,比如在旧应用程序中定期调用Application.DoEvents)。好又通用,只要长时间运行的代码有利于循环map() - 样式操作!