Javascript Jquery一次循环和绑定10条记录

Javascript Jquery一次循环和绑定10条记录,javascript,jquery,Javascript,Jquery,我有一个场景,从服务器获取数千条记录作为JSON,并将所有记录绑定到页面。对于每条记录,我在jquery中进行一些计算,并将数据绑定到UI。由于记录计数为1000,计算和绑定数据所需的时间更长。完成所有记录计算后,页面上的数据将在末尾绑定。是否有任何选项可以逐个绑定数据或10×10绑定数据,并在UI上显示该集合的绑定。我试图找到的是每次为10条记录执行$。并向其追加下一组10条记录,以此类推。有没有办法让页面加载更快?(我的要求不需要分页)。任何线索都有帮助 <div id="keepFi

我有一个场景,从服务器获取数千条记录作为JSON,并将所有记录绑定到页面。对于每条记录,我在jquery中进行一些计算,并将数据绑定到UI。由于记录计数为1000,计算和绑定数据所需的时间更长。完成所有记录计算后,页面上的数据将在末尾绑定。是否有任何选项可以逐个绑定数据或10×10绑定数据,并在UI上显示该集合的绑定。我试图找到的是每次为10条记录执行$。并向其追加下一组10条记录,以此类推。有没有办法让页面加载更快?(我的要求不需要分页)。任何线索都有帮助

<div id="keepFinalDataHere"></div>


$.each(data, function (i, record) {

 content += "<div>" + record.id + "</div><div>" + record.fromId + "</div><div>" + record.subject + "</div>";
        });

    $(content).appendTo('#keepFinalDataHere');

$。每个(数据、功能(i、记录){
内容+=“”+record.id+“”+record.fromId+“”+record.subject+“”;
});
$(content).appendTo('keepFinalDataHere');

在上面的代码中,内容是通过获取数千条记录来构建的,一旦构建了内容,就将其绑定到div。我正在寻找一个选项,让前10项绑定数据,以确保用户感觉页面已加载,然后将100个左右的剩余项添加到现有列表中。

如果您从服务器获取的数据量有问题,您应该找到一种方法来限制数组

因此,您的客户机代码可以处理适当数量的元素,即您可以向用户显示的元素

若这是不可能的,并且您希望在客户端完成所有工作,那个么您应该有一个更复杂的方法

您必须保存指向已处理元素的指针,以及一个包含要处理元素数量的变量(page num?)

然后对循环使用

// Globally but not global
var cursor = 0

... 


for(var i = cursor; i < (cursor+pageNum); i++) {
    var element = myDataAsJsonFromApi[i];
    // ... do something here.
}

// check if pageNum elements is added..
cursor += pageNum

if (myDataAsJsonFromApi.length == cursor) {
 // load from server...
}
//全局而非全局
变量游标=0
... 
对于(变量i=光标;i<(光标+页面编号);i++){
var元素=myDataAsJsonFromApi[i];
//…在这里做点什么。
}
//检查是否添加了pageNum元素。。
光标+=页面编号
if(myDataAsJsonFromApi.length==游标){
//从服务器加载。。。
}

一个选项是将数据缓冲区分割成块,这样您就可以一次对一些数据进行操作

var data = [1,2,3,4,5,6,7,7,8,9,9,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,89];

(function () {

  var lastSliceStart = 0;

  function writeNext() {
    var length = 10;
    var chunk = $(data).slice(lastSliceStart, lastSliceStart+length);

    $(chunk).each((key, item) => {
      console.log(item);
    });

    lastSliceStart += length;

    if (lastSliceStart < data.length) {
      setTimeout(writeNext, 500); // Wait .5 seconds between runs
    }
  }

  writeNext();

})();
var数据=[1,2,3,4,5,6,7,7,8,9,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,89];
(功能(){
var lastSliceStart=0;
函数writeNext(){
变量长度=10;
var chunk=$(数据).slice(lastSliceStart,lastSliceStart+长度);
$(块)。每个((键,项)=>{
控制台日志(项目);
});
lastSliceStart+=长度;
if(lastSliceStart

如果您希望保持UI的响应性,并希望能够在呈现大量DOM元素之间执行代码,则必须使用超时机制。可以通过将渲染方法传递给来执行此操作

setTimeout
将方法推送到任务队列中,而不是将方法添加到堆栈中并立即执行,并且只在当前js堆栈清除后执行

我提议的方法的主要步骤是:

  • 将数据集复制到临时阵列
  • 使用
    splice
    从阵列中删除第一个
    n
  • 将第一个
    n
    项呈现到DOM
  • 如果仍有剩余项目,请转至(2)
  • 下面是代码的主要部分,带有注释,假设:

    • testData
      保存一组数据点
    • createRow
      保存将数据点转换为渲染DOM元素的逻辑
    • INITIAL\u CHUNK\u SIZE
      保存要在不超时的情况下渲染的行数
    • DEFAULT\u CHUNK\u SIZE
      保存每个循环必须渲染的行数
    超时渲染器(
    torender
    ):

    在下面的示例中,我使用了一个移动微调器来显示渲染循环如何能够保持适当的帧速率

    请注意,
    DEFAULT\u CHUNK\u SIZE
    越大,渲染所有项目的速度就越快。折衷:一旦一个渲染块的时间超过1/60秒,就会降低平滑帧速率

    //设置
    var数据_长度=10000;
    var默认块大小=100;
    var初始块大小=10;
    风险值列表=文件查询选择器(“ul”);
    var createRow=函数(数据){
    var div=document.createElement(“div”);
    div.innerHTML=数据;
    名单.附属儿童(分区);;
    };
    //阻塞,直到渲染所有行
    var bruteRenderer=函数(){
    console.time(“暴力渲染器总时间:”);
    testData.forEach(createRow);
    timeEnd(“暴力渲染器总时间:”);
    }
    //将“渲染指定”推送到“任务组”
    var-torender=函数{
    控制台时间(“超时渲染器总时间:”;
    var-dataBuffer=[].concat(testData);
    var nextRender=函数{
    var chunkSize=s | |缺省_CHUNK_SIZE;
    数据缓冲器
    .拼接(0,块大小)
    .forEach(createRow);
    if(数据缓冲长度){
    设置超时(nextRender);
    }否则{
    timeEnd(“超时渲染器总时间:”);
    }
    };
    nextRender(初始块大小);
    };
    //示例数据、事件侦听器:
    //生成测试数据
    var testData=(函数(){
    var结果=[];
    对于(变量i=0;i
    
    按钮{
    显示:内联块;
    保证金权利:.5rem;
    }
    斯宾纳先生{
    背景:红色;
    边界半径:50%;
    宽度:20px;
    高度:20px;
    动画持续时间:1s;
    动画计时功能:线性;
    动画方向:交替;
    动画名称:移动;
    动画迭代
    
    var toRenderer = function(s) {
      // We need a copy because `splice` mutates an array
      var dataBuffer = [].concat(testData);
    
      var nextRender = function(s) {
        // Default value that can be overridden
        var chunkSize = s || DEFAULT_CHUNK_SIZE; 
    
        dataBuffer
          .splice(0, chunkSize)
          .forEach(createRow);
    
        if (dataBuffer.length) {
          setTimeout(nextRender);
        }
      };
    
      // Triggers the initial (not timed out) render
      nextRender(INITIAL_CHUNK_SIZE);
    };
    
    //your app
    App = {
        data: [] //set your JSON dataSource here
    }
    
    //define Task
    Task = function () {        
        this.buildQueue(10);
    };
    Task.prototype = {
        buildQueue: function (size) {
            var data_count = App.data.length; //length of your datasource
            this.queue = [];                        
            // fill the queue
            var lastIndex = 0;
            var current_index = size;
            var c = true;
            while (c) {
                if (current_index >= data_count - 1) {
                    current_index = data_count;
                    c = false;
                }
                this.queue.push([lastIndex, current_index - 1]);
                lastIndex = current_index;
                current_index += size;
            }
            /* If size is 10, array would be [[0,9], [10,19], [20,29]....and so on], The smaller the size, better progress / percentage variation  / loading on ui display */
        },
        doNext: function () {
            if (this.queue.length == 0) {
                this.end();
                return;
            }            
            var row = this.queue.shift(); //stack is LIFO, queue is FIFO, this.queue.pop()
            try {
                this.processQueue(App.data, row[0], row[1]); //pass dataSource, and indexes of array, loop in processQueue function for indexes passed
            } catch (e) {                
                return;
            }
            this.incrementProgress(row[1] / App.data.length); //progress on ui
            // do next
            var _self = this;
            setTimeout(function () {
                _self.doNext();
            }, 1);
        },
        incrementProgress: function (percent) {
            var $progress = $('#percent');
            percent = Math.ceil(percent * 100);
            percent = percent + '%';
            $progress.text(percent);
        },
        start: function () {            
            $('#percent').show();
            this.doNext(); //initiate loop
        },
        end: function () {            
            $('#percent').hide();            
        },
        processQueue: function (data, start, end) {            
            for (var i = start; i <= end; i++) {                
                var dataObj = data[i];
                //use the data here, update UI so user sees something on screen
            }
        }
    };
    
    //initialize an instance of Task
    var _task = new Task(task); 
    _task.start();    
    
     <div id="keepFinalDataHere"></div>
    
    <script>
    //.../ 
    
    var chunkSize = 50;//what ever you want or could be dynamic based on data size
    var $keepFinalDataHere = $('#keepFinalDataHere');
    $.each(data, function (i, record) {
      content += "<div>" + record.id + "</div><div>" + record.fromId + "</div><div>" + record.subject + "</div>";
         if(i % chunkSize === 0){ // content chunk is ready
              $keepFinalDataHere.append(content); // show records
              content = '';//reset the content
             }
        });
    if(!(content === '')){//any leftOver records
       $keepFinalDataHere.append(content);
     }