Dojo:使用setTimeout以异步方式加载小部件 [英] Dojo: using setTimeout to load widgets in async way

查看:961
本文介绍了Dojo:使用setTimeout以异步方式加载小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下,我们有一个序列小部件,加载元素小部件,并为其中的每个添加一些配置(通过 loadConfig())。下图中描述了Schematic视图:

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();
});

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

有没有办法一个一个地加载和显示元素,而不是一次加载所有的东西? JavaScript没有多线程..所以我真的用完了想​​法。

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.

编辑:试图使用 setTimeout()在这个伟大的答案中建议为什么setTimeout(fn,0)有时是有用的?
但这并不能解决问题。看起来Dojo有一些可以防止小部件逐个呈现的东西 - 加载所有数据时加载它们,然后将它们全部加载。

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 :这是如何 setTimeout()被试图使用:

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

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

EDIT3 :这是完整的代码。层次结构是: TestSequence> Test> ElementsGroup> Element

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


推荐答案

解决方案是使用 setTimeout 以及递归函数,如下所示:

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])

UI线程仍然是错误的,但至少它没有被冻结。该解决方案被选为快速解决方案。对于一个很长的人,决定优化代码以摆脱同步XHR请求。

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.

这篇关于Dojo:使用setTimeout以异步方式加载小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆