Dojo: using setTimeout to load widgets in async way

独自空忆成欢 提交于 2019-12-25 03:53:09

问题


Imagine that we have a Sequence widget which loads Element widgets and loads some config for each of them (through loadConfig()) .Schematic view is described on the image below:

The problem is that every approach I tried does the same "bad" thing: it freezes everything until all Elements are loaded.

array.forEach(elements, function(element) {
  element.loadConfig();
});

or

var counter = 0;
var loadConfig = function(element) {
  element.loadConfig()
  if (++counter <= elements.length - 1) {
    loadConfig(elements(counter));
  }
};
loadConfig(0);

Is there any way to load and show elements one by one, instead of trying to load everything at once? JavaScript doesn't have multi-threading.. so I am really running out of ideas.

EDIT: Tried to use setTimeout() as suggested in this great answer Why is setTimeout(fn, 0) sometimes useful? But this doesn't solve the problem. Looks like Dojo has something that prevents widgets to be rendered one by one - it loads while all data is loaded and then load them all together.

EDIT2: This is how setTimeout() was tried to be used:

array.forEach(elements, function(element) {
  setTimeout(function() {
    element.loadConfig();
  }, 0);
});

EDIT3: Here is full code what is going on. The hierarchy is: 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.
},
...

回答1:


The solution was to use setTimeout along with recursive function, like this:

var counter = 0;

recursiveFunc: function(element) {
  setTimeout(function() {
    // Do stuff for element[counter]

    if (++counter < numberOfElements) {
      recursiveFunc(element);
    }
  }, 0);
}

recursiveFunc(element[counter])

The UI thread would still be buggy, but at least it is not frozen. This solution was picked as a fast one. For a long-one it was decided to optimize the code to get rid of sync XHR request.



来源:https://stackoverflow.com/questions/33145579/dojo-using-settimeout-to-load-widgets-in-async-way

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!