如何对上万条数据进行展示

一、后端

后端通过分页方法将所有数据分成n页,将前端需要展示的对应页数据返回

二、前端

1.懒加载(分批加载)

前端实现分页功能

    var count = 10;//10条数据一页
    function sliceArray(getArr) {
        var totalArr = [];
        for (var i = 0; i < allArr.length; i += count) {
            totalArr.push(allArr.slice(i, i + count));
        }
        console.log('分割后的数组:', totalArr);
        if(totalArr.length < 1){
            console.log('没有数据');
        }
        //分割完数据后进行首次加载数据,为了避免只加载第一条没有滚动条出现的问题,使用以下的代码使首次加载完后必定出现滚动条
        for(var i = 0; i < totalArr.length; i ++){
            if($(document).height() <= $(window).height()){
                //没有滚动条
                loadData(totalArr[i]);
                totalArrIndex = i;
            }else{
                break;
            }
        }
    }

如果还去要对数据进行前端筛选:

function checkArr(arr, str) {
    var resData = [];
    $.each(arr, function (i, value) {
        var reg = new RegExp(value);//转换成正则表达式
        var regData = null;
        if(str.match(reg) != null){
            //匹配成功
            resData.push(value);
        }
    });
    return resData;
}

2.worker

什么是worker

简单来讲JS是单线程运行的,如果遇到一些需要处理大量数据的JS时,可能会阻塞页面的加载,造成页面假死。使用worker则可以为我们开辟一个独立于主线程之外的子线程用于大量数据的复杂计算。

worker的语法

const worker = new Worker(aURL, options)

aURL(必须)是一个DOMString 表示worker 将执行的脚本的URL。它必须遵守同源策略。
options (可选)它的一个作用就是指定 Worker 的名称,用来区分多个 Worker 线程

worker的属性

  • worker.onerror:指定 error 事件的监听函数
  • worker.onmessage:指定 message 事件的监听函数,发送过来的数据在Event.data属性中。
  • worker.onmessageerror:指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件。

worker的方法

  • worker.postMessage():向 Worker 线程发送消息。
  • worker.terminate():立即终止 Worker 线程。

使用worker的注意点

  1. 同源限制
    分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。
  2. DOM 限制
    worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。但是,Worker 线程可以使用navigator对象和location对象。
  3. 通信联系
    worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。
  4. 脚本限制
    worker 线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。
  5. 文件限制
    worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。

worker的使用案例

a.html:

<html>
<head>
    <title></title>
</head>
<body>
<script>
    onload =function(){
        var worker =new Worker('worker.js');
        worker.addEventListener('message', function(event) {
            var timer2 = (new Date()).valueOf();
            console.log( '结果:'+event.data, '时间:'+ timer2, '用时:'+ ( timer2  - timer ) );
        }, false);
        var timer = (new Date()).valueOf();
        console.log('开始计算:40','时间:'+ timer );
        setTimeout(function(){
            console.log('定时器函数在计算数列时执行了', '时间:'+ (new Date()).valueOf() );
        },1000);
        worker.postMessage(40);
        console.log('我在计算数列的时候执行了', '时间:'+ (new Date()).valueOf() );
    }
</script>
</body>
</html>

worker.js:

self.onmessage = function(event) {
    var data = event.data;
    var ans = fibonacci(data);
    this.postMessage(ans);
};
function fibonacci(n) {
    return n < 2 ? n: arguments.callee(n - 1) + arguments.callee(n - 2);
}

以下为输出结果:
开始计算:40 时间:1559180522741
我在计算数列的时候执行了 时间:1559180522741
定时器函数在计算数列时执行了 时间:1559180523750
结果:102334155 时间:1559180529714 用时:6973

这个例子说明在worker中执行的fibonacci数列的计算并不会影响到主线程的代码执行,完全在自己独立的线程中计算,只是在计算完成之后将结果发回主线程。

利用web worker我们可以在前端执行一些复杂的大量运算而不会影响页面的展示,并且不会弹出恶心的脚本正忙提示。

worker的其他用途

我们已经知道Worker通过接收一个URL来创建一个worker,那么我们是否可以利用web worker来做一些类似jsonp的请求呢,大家知道jsonp是通过插入script标签来加载json数据的,而script元素在加载和执行过程中都是阻塞式的,如果能利用web worker实现异步加载将会非常不错。

下面这个例子将通过 web worker、jsonp、ajax三种不同的方式来加载一个169.42KB大小的JSON数据

// /aj/webWorker/core.js
function $E(id) {
    return document.getElementById(id);
}
onload =function() {
    //通过web worker加载
    $E('workerLoad').onclick =function() {
        var url ='http://js.wcdn.cn/aj/mblog/face2';
        var d = (new Date()).valueOf();
        var worker =new Worker(url);
        worker.onmessage =function(obj) {
            console.log('web worker: '+ ((new Date()).valueOf() - d));
        };
    };
    //通过jsonp加载
    $E('jsonpLoad').onclick =function() {
        var url ='http://js.wcdn.cn/aj/mblog/face1';
        var d = (new Date()).valueOf();
        STK.core.io.scriptLoader({
            method:'post',
            url : url,
            onComplete : function() {
                console.log('jsonp: '+ ((new Date()).valueOf() - d));
            }
        });
    };
    //通过ajax加载
    $E('ajaxLoad').onclick =function() {
        var url ='http://js.wcdn.cn/aj/mblog/face';
        var d = (new Date()).valueOf();
        STK.core.io.ajax({
            url : url,
            onComplete : function(json) {
                console.log('ajax: '+ ((new Date()).valueOf() - d));
            }
        });
    };
};
//HTML页面:/aj/webWorker/worker.html
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Worker example: load data</title>
<script src="http://js.t.sinajs.cn/STK/js/gaea.1.14.js" type="text/javascript"></script>
<script type="text/javascript" src="http://js.wcdn.cn/aj/webWorker/core.js"></script>
</head>
<body>
    <input type="button" id="workerLoad" value="web worker加载"></input>
    <input type="button" id="jsonpLoad" value="jsonp加载"></input>
    <input type="button" id="ajaxLoad" value="ajax加载"></input>
</body>
</html>
//设置HOST
127.0.0.1 js.wcdn.cn

通过访问worker.html页面然后分别通过三种方式加载数据,得到控制台输出:

web worker: 174
jsonp: 25
ajax: 38

多试几次发现通过jsonp和ajax加载数据的时间相差不大,而web worker的加载时间一直处于高位,所以用web worker来加载数据还是比较慢的,即便是大数据量情况下也没任何优势,可能是Worker初始化新起线程比较耗时间。除了在加载过程中是无阻塞的之外没有任何优势。

总结

worker可以做:

1.可以加载一个JS进行大量的复杂计算而不挂起主进程,并通过postMessage,onmessage进行通信

2.可以在worker中通过importScripts(url)加载另外的脚本文件

3.可以使用 setTimeout(), clearTimeout(), setInterval(), and clearInterval()

4.可以使用XMLHttpRequest来发送请求

5.可以访问navigator的部分属性

局限性:

1.不能跨域加载JS

2.worker内代码不能访问DOM

3.各个浏览器对Worker的实现不大一致,例如FF里允许worker中创建新的worker,而Chrome中就不行

4.不是每个浏览器都支持这个新特性

https://juejin.im/post/5cb03fbee51d456e853f810b
https://www.cnblogs.com/feng_013/archive/2011/09/20/2175007.html

猜你喜欢

转载自blog.csdn.net/yanyihan16/article/details/90675864