道场:使用setTimeout的加载在异步方式部件 [英] Dojo: using setTimeout to load widgets in async way

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

问题描述

假设我们有它加载为每个元素部件和负载一些配置一个部件(通过 loadConfig()).Schematic视图下面的图片描述:

在这里输入的形象描述

问题是,每一个方法我试图做同样的坏的事情。直到所有的元素加载它冻结一切

  array.forEach(元素,功能(元素){
  element.loadConfig();
});

  VAR计数器= 0;
VAR loadConfig =功能(元素){
  element.loadConfig()
  如果(++计数器< = elements.length - 1){
    loadConfig(元素(计数器));
  }
};
loadConfig(0);

有什么办法接一个地加载和显示元件中的一个,而不是试图一次加载的一切吗? JavaScript没有多线程..所以我真的很运行的想法。

编辑:试过使用的setTimeout()的建议在这个伟大的答案<一个href=\"https://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful/4575011#4575011\">Why是的setTimeout(FN,0)有时是有用的?
但是,这并不解决问题。看起来道场有一些prevents部件由一个被渲染之一 - 它装载而所有的数据加载,然后加载它们放在一起

EDIT2 :这是如何的setTimeout()已尝试使用:

  array.forEach(元素,功能(元素){
  的setTimeout(函数(){
    element.loadConfig();
  },0);
});

EDIT3 :这里充满code是怎么回事。该层次是: TestSequence>测试> ElementsGroup>元素

  //内部TestSequence部件:
...
无功配置= [someConfig1,someConfig2,... someCondigN]array.forEach(sequenceConfig,功能(sequenceConfigItem,I){
  需要(['SOME_PATH /+ sequenceConfig.type]功能(CLS){
    VAR测试=全新CLS();
    test.set('配置',sequenceConfigItem);
  });
}, 这个);
...
//内部测试窗口小部件
...
_setConfigAttr:功能(testConfig){
  elementsGroup.set('配置',testConfig);
},
...
//内部ElementsGroup部件
...
_setConfigAttr:功能(elementsGroupConfig){
  array.forEach(配置,功能(elemenstGroupConfigItem,I){
    需要(['SOME_PATH /+ elementsGroupConfigItem.type]功能(CLS){
      VAR元=全新CLS(); //&LT; ---除去该解决问题
      element.set('配置',elementsGroupConfigItem);
    });
  }, 这个);
},
...
//元素中小部件
...
_setConfigAttr:功能(testConfig){
  //将简单的DOM的东西 - 设置名称,说明等。
},
...


解决方案

该解决方案是使用的setTimeout 与递归函数一起,像这样的:

  VAR计数器= 0;recursiveFunc:函数(元素){
  的setTimeout(函数(){
    //做的东西为元素[窗口]    如果(++计数器&LT; numberOfElements){
      recursiveFunc(元件);
    }
  },0);
}recursiveFunc(元素[窗口])

在UI线程仍然是越野车,但至少它没有冻结。该解决方案被选为一快一。在很长一就决定优化code摆脱同步XHR请求。

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

解决方案

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.

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

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