我有一个纯CSS微调器,我想在我的JavaScript做其他工作时显示(异步调用,然后迭代大约10,000个元素的数组)。微调器出现在正确的时间,但在代码中的某个点被击中时会冻结。在下面的代码中,'one','two'和'three'的var HtmlWebpackPlugin = require('html-webpack-plugin');
var htmlWebpackTemplate = require('html-webpack-template');
var uiContext = require('./server/ui-context');
// ...
plugins: [
new HtmlWebpackPlugin({
template: htmlWebpackTemplate,
window: {
uiContext
}
}),
s基本上立即发生 - 然后有一个很长的停顿(当我的微调器冻结时)然后'四'和'五'一起注销,我的内容加载。所以基本上我知道“console.log
”和“console.log('three')
”之间的代码:
console.log('four')
我尝试的每个纯CSS微调器都会发生这种情况。
我认为我的JavaScript不应该冻结我的纯CSS微调器我错了吗?为什么代码会冻结呢?
答案 0 :(得分:4)
JavaScript在UI线程上运行,因此它仍将阻止仅CSS的微调器。您需要将工作从UI线程移开或拆分,以便UI有时间更新。
根据您需要支持的浏览器,您可以使用Web Workers。有关浏览器支持,请参阅http://caniuse.com/#search=web%20workers或举例说明http://www.html5hacks.com/blog/2012/09/22/web-workers-basics-of-the-web-browsers-ui-thread/。
您还可以一次处理一个(或10个或100个)记录,然后调用每个"批次"在window.setTimeout
或window.requestAnimationFrame
内。尝试这样的事情(代码未经过测试):
// for search bar
search(text) {
this.searching = true; // shows spinner
console.log('one');
var text = text.toUpperCase();
// search the text with an api call
this.securitiesService.searchSecurities(text)
.subscribe(data => {
var response = data.response;
console.log('two');
// if no search results are present go to correct page
if (!response.length) {
this.router.navigate(...to route...);
return;
}
console.log('three');
var i = 0;
var self = this;
var processBatch = function () {
if (text === response[i].ticker) {
console.log('four');
self.router.navigate(...to route...);
self.searching = false;
console.log('five');
return;
}
if (++i < response.length) {
window.setTimeout(processBatch, 0);
}
};
window.setTimeout(processBatch, 0);
});
}
如果您希望每批处理多个项目,则可以在processBatch
内设置一个循环来迭代少量项目。
旁注:如果data.response
是字符串,请参阅@ gelliott181上面的评论。