Dojo:使用 setTimeout 以异步方式加载小部件

Dojo: using setTimeout to load widgets in async way

假设我们有一个 Sequence 小部件,它加载 Element 个小部件并为每个小部件加载一些配置(通过 loadConfig())。示意图如下图所示:

问题是我尝试过的每一种方法都做同样的事情 "bad":它会冻结所有内容,直到加载所有 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 > Test > ElementsGroup > Element.

// 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.
},
...

解决方案是将 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 请求。