Dojo:使用setTimeout以异步方式

时间:2015-10-15 10:04:16

标签: javascript multithreading asynchronous dojo settimeout

想象一下,我们有一个Sequence窗口小部件,可以加载Element窗口小部件并为每个窗口小部件加载一些配置(通过loadConfig())。示意图如下图所示:

enter image description here

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

1 个答案:

答案 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请求。