当前位置:  开发笔记 > 编程语言 > 正文

如何在密集的JavaScript处理过程中(简要地)向浏览器提供控制权?

如何解决《如何在密集的JavaScript处理过程中(简要地)向浏览器提供控制权?》经验,为你挑选了2个好方法。

我在这里阅读了关于在密集DOM处理(使用JavaScript)期间使用setTimeout()的帖子,但是如何将此函数与下面的代码集成?以下代码适用于少量选项,但当选项数量太大时,我的"请等待"动画GIF会在本地JavaScript处理时冻结.谢谢!

function appendToSelect() {
    $("#mySelect").children().remove() ;
    $("#mySelect").html(
        ''
    );
    var j = 1 ;
    for (var i = 1; i < obj.data.length; i++) {
        $("#mySelect").append(
            ''
        ); 
    }
}

Jason Buntin.. 29

这是一个解决方案:

function appendToSelect() {
  $("#mySelect").children().remove();
  $("#mySelect").html(
    ''
  );
  obj.data.splice(0, 1); // we only want remaining data
  var appendOptions = function() {
    var dataChunk = obj.data.splice(0, 10); // configure this last number (the size of the 'chunk') to suit your needs
    for(var i = 0; i < dataChunk.length; i++) {
      $("#mySelect").append(
        ''
      );
    }
    if(obj.data.length > 0) {
      setTimeout(appendOptions, 100); // change time to suit needs
    }
  };
  appendOptions(); // kicks it off
}

不像@Borgar的解决方案那么优雅,但你明白了.基本上,我正在做同样的事情,但是在你的一个函数中,而不是像他那样将它分解为更高阶的函数.我喜欢他的解决方案,但如果你不喜欢,也许这对你有用.


编辑:对于那些没有立即看到它的人来说,这个解决方案和@ Borgar之间的主要区别之一是这个解决方案允许你设置每次超时之间处理的数据"块"的大小.@Borgar在处理完每个数组成员后的超时时间.如果我有时间,我会尝试创建一个更高阶的函数来处理这个,所以它更优雅.虽然没有承诺!;)


编辑:所以,这是我改编的@Borgar的解决方案,它允许设置'块'大小并更容易配置超时值:

function incrementallyProcess(workerCallback, data, chunkSize, timeout, completionCallback) {
  var itemIndex = 0;
  (function() {
    var remainingDataLength = (data.length - itemIndex);
    var currentChunkSize = (remainingDataLength >= chunkSize) ? chunkSize : remainingDataLength;
    if(itemIndex < data.length) {
      while(currentChunkSize--) {
        workerCallback(data[itemIndex++]);
      }
      setTimeout(arguments.callee, timeout);
    } else if(completionCallback) {
      completionCallback();
    }
  })();
}

function appendToSelect() {
  $("#mySelect").children().remove();
  $("#mySelect").html(
    ''
  );
  obj.data.splice(0,1); // we only want remaining data      
  incrementallyProcess(function(data) {
    $("#mySelect").append(
    ''
   );
  }, obj.data, 10, 100, removeAnimatedGifFunction); // last function not required...
}

希望有所帮助 - 我认为这结合了两种解决方案的优点.注意,第二个匿名函数不再使用索引值,而只是传递整个对象(带有value和name属性); 因为当迭代事物时,当前对象的索引通常不是那么有用,所以它会变得更清晰一些.

我相信仍然有一些事情可以做到更好,但这仍然是读者的练习.;)



1> Jason Buntin..:

这是一个解决方案:

function appendToSelect() {
  $("#mySelect").children().remove();
  $("#mySelect").html(
    ''
  );
  obj.data.splice(0, 1); // we only want remaining data
  var appendOptions = function() {
    var dataChunk = obj.data.splice(0, 10); // configure this last number (the size of the 'chunk') to suit your needs
    for(var i = 0; i < dataChunk.length; i++) {
      $("#mySelect").append(
        ''
      );
    }
    if(obj.data.length > 0) {
      setTimeout(appendOptions, 100); // change time to suit needs
    }
  };
  appendOptions(); // kicks it off
}

不像@Borgar的解决方案那么优雅,但你明白了.基本上,我正在做同样的事情,但是在你的一个函数中,而不是像他那样将它分解为更高阶的函数.我喜欢他的解决方案,但如果你不喜欢,也许这对你有用.


编辑:对于那些没有立即看到它的人来说,这个解决方案和@ Borgar之间的主要区别之一是这个解决方案允许你设置每次超时之间处理的数据"块"的大小.@Borgar在处理完每个数组成员后的超时时间.如果我有时间,我会尝试创建一个更高阶的函数来处理这个,所以它更优雅.虽然没有承诺!;)


编辑:所以,这是我改编的@Borgar的解决方案,它允许设置'块'大小并更容易配置超时值:

function incrementallyProcess(workerCallback, data, chunkSize, timeout, completionCallback) {
  var itemIndex = 0;
  (function() {
    var remainingDataLength = (data.length - itemIndex);
    var currentChunkSize = (remainingDataLength >= chunkSize) ? chunkSize : remainingDataLength;
    if(itemIndex < data.length) {
      while(currentChunkSize--) {
        workerCallback(data[itemIndex++]);
      }
      setTimeout(arguments.callee, timeout);
    } else if(completionCallback) {
      completionCallback();
    }
  })();
}

function appendToSelect() {
  $("#mySelect").children().remove();
  $("#mySelect").html(
    ''
  );
  obj.data.splice(0,1); // we only want remaining data      
  incrementallyProcess(function(data) {
    $("#mySelect").append(
    ''
   );
  }, obj.data, 10, 100, removeAnimatedGifFunction); // last function not required...
}

希望有所帮助 - 我认为这结合了两种解决方案的优点.注意,第二个匿名函数不再使用索引值,而只是传递整个对象(带有value和name属性); 因为当迭代事物时,当前对象的索引通常不是那么有用,所以它会变得更清晰一些.

我相信仍然有一些事情可以做到更好,但这仍然是读者的练习.;)



2> Borgar..:

碰巧我刚刚在这里发布了这个帖子.这是一个定时循环函数:

function processLoop( actionFunc, numTimes, doneFunc ) {
  var i = 0;
  var f = function () {
    if (i < numTimes) {
      actionFunc( i++ );  // closure on i
      setTimeout( f, 10 )
    } 
    else if (doneFunc) { 
      doneFunc();
    }
  };
  f();
}

对于您的情况,这将使用如下:

function appendToSelect () {

  $("#mySelect").children().remove() ;
  $("#mySelect").html(
      ''
  );
  var j = 1 ;

  processLoop(function (i){
    $("#mySelect").append(
        ''
    ); 
  }, obj.data.length);

}

您需要确保在迭代函数中有一个闭包或对obj变量的其他访问.

希望这可以帮助.

推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有