想象一下,我们有一个Sequence
窗口小部件,可以加载Element
窗口小部件并为每个窗口小部件加载一些配置(通过loadConfig()
)。示意图如下图所示:
问题是我尝试过的每一种方法都做同样的事情"糟糕的"事情:它会冻结所有内容,直到加载所有Elements
。
array.forEach(elements, function(element) {
element.loadConfig();
});
或
var counter = 0;
var loadConfig = function(element) {
element.loadConfig()
if (++counter <= elements.length - 1) {
loadConfig(elements(counter));
}
};
loadConfig(0);
有没有办法逐个加载和显示元素,而不是尝试一次加载所有内容? JavaScript并没有多线程......所以我真的没有想法了。
编辑:按照这个伟大的回答Why is setTimeout(fn, 0) sometimes useful?的建议,尝试使用setTimeout()
但这并没有解决问题。看起来Dojo有一些东西可以阻止小部件逐个呈现 - 它会在加载所有数据时加载,然后将它们一起加载。
EDIT2 :这是setTimeout()
尝试使用的方式:
array.forEach(elements, function(element) {
setTimeout(function() {
element.loadConfig();
}, 0);
});
EDIT3 :这是完整的代码。层次结构是: TestSequence&gt;测试&gt; ElementsGroup&gt;元件
// Inside TestSequence widget:
...
var config = [someConfig1, someConfig2, ... someCondigN]
array.forEach(sequenceConfig, function(sequenceConfigItem, i) {
require(['some_path/' + sequenceConfig.type], function(cls) {
var test = new cls();
test.set('config', sequenceConfigItem);
});
}, this);
...
// Inside Test widget
...
_setConfigAttr: function(testConfig) {
elementsGroup.set('config', testConfig);
},
...
// Inside ElementsGroup widget
...
_setConfigAttr: function(elementsGroupConfig) {
array.forEach(config, function(elemenstGroupConfigItem, i) {
require(['some_path/' + elementsGroupConfigItem.type], function(cls) {
var element = new cls(); // <--- removing this solves the problem
element.set('config', elementsGroupConfigItem);
});
}, this);
},
...
// Inside Element widget
...
_setConfigAttr: function(testConfig) {
// apply simple DOM-stuff - set name, description, etc.
},
...
答案 0 :(得分:0)
解决方案是使用setTimeout
和递归函数,如下所示:
var counter = 0;
recursiveFunc: function(element) {
setTimeout(function() {
// Do stuff for element[counter]
if (++counter < numberOfElements) {
recursiveFunc(element);
}
}, 0);
}
recursiveFunc(element[counter])
UI线程仍然是错误的,但至少它没有被冻结。这个解决方案被选为快速解决方案。很长一段时间,我们决定优化代码以摆脱同步XHR请求。