• JavaScript多线程之HTML5 Web Worker


    JavaScript多线程之HTML5 Web Worker ---真正意义的js多线程(主要用来处理js程序本身的一些阻塞操作,除了复杂的计算,想不到有其他的js自身的阻塞操作--(因为js本身不能操作文件操作,....这些耗时的IO操作。)为什么不提图片加载,ajax,这些异步操作呢?因为这些对于js主线程来说是非阻塞的,他们是在浏览器上重新开的线程上执行的,通过回调和js主程序联系在一起,他们是浏览器多线程的意义,并不是js真正自己的多线

    在博主的前些文章Promise的前世今生和妙用技巧JavaScript单线程和浏览器事件循环简述中都曾提到了HTML5 Web Worker这一个概念。在JavaScript单线程和浏览器事件循环简述中讲述了JavaScript出于界面元素访问安全的考虑,所以JavaScript运行时一直是被实现为单线程执行的;这也意味着我们应该尽量的避免在JavaScript中执行较长耗时的操作(如大量for循环的对象diff等)或者是长时间I/O阻塞的任务,特别是对于CPU计算密集型的操作。

    例如在JavaScript中尝试计算像fibonacci这类计算密集型的操作,就会导致整个页面体验被blocked。HTML5 Web Worker的出现让我们在不阻塞当前JavaScript线程的情况下,在当前的JavaScript执行线程中可利用Worker这个类新开辟一个额外的线程来加载和运行特定的JavaScript文件,这个新的线程和JavaScript的主线程之间并不会互相影响和阻塞执行的;并且在Web Worker中提供这个新线程和JavaScript主线程之间数据交换的接口:postMessage和onmessage事件。它和C# WinForm中的BackgroundWorker很类似。

    Web Worker实现fibonacci计算

    利用HTML5 Web Worker实现fibonacci可像如下所示(plnkr在线demo):

    fibonacci.js Worker JavaScript文件:

    (function() {
      var fibonacci = function(n) {
        return n < 2 ? 1 : (fibonacci(n - 1) + fibonacci(n - 2));
      };
    
      onmessage = function(event) {
        postMessage({
          input: event.data,
          result: fibonacci(event.data)
        });
      };
    
    })();
    

    在fibonacci.js中利用onmessage方法来监听主线程发送的fibonacci计算请求,和利用postMessage返回计算的结果到请求线程。

    script.js 主线程JavaScript文件:

    $(function() {
      var $input = $('#input'),
        $btn = $('#btn'),
        $result = $('#result'),
        worker = new Worker('fibonacci.js'),
        timeKey = function(val) {
          return 'fibonacci(' + val + ')';
        };
    
      worker.onmessage = function(event) {
        console.timeEnd(timeKey(event.data.input));
        $result.text(event.data.result);
      };
    
      $btn.on('click', function() {
        var val = parseInt($input.val(), 10);
        if (val) {
          console.time(timeKey(val));
          $result.text('?')
          worker.postMessage(val);
        }
      });
    });
    

    在这个JavaScript文件中,利用new Worker('fibonacci.js')方式来创建Web Worker对象,并利用Worker对象上的postMessage方法发送请求计算请求,以及利用Worker对象的onmessage的方法接受Worker线程的返回结果,并显示在UI界面上。同时我们也利用了console最新的time API来统计计算所花费的时间。

    其显示效果如下:

    html5 web worker demo

    在console中打印的时间信息为:

    fibonacci(10): 1.022ms
    fibonacci(20): 1.384ms
    fibonacci(30): 22.065ms
    fibonacci(40): 1744.352ms
    fibonacci(50): 202140.027ms
    

    从这里时间输出可以看出,在计算n为40的fibonacci 开始时间开始急速的加长,在UI中返回结果的时间也逐渐变长;但是在Web Worker后台计算的时候,它并不会阻塞我们的UI界面的其他交互。

    Web Worker总结

    Web Worker在这类耗时计算密集型操作中,显得特别实用。在Web Worker中我们可以实现:

    1. 可以加载一个JS进行大量的复杂计算而不挂起主进程,并通过postMessage,onmessage进行通信;
    2. 可以在worker中通过importScripts(url)加载另外的脚本文件;
    3. 可以使用 setTimeout(),clearTimeout(),setInterval(),clearInterval();
    4. 可以使用XMLHttpRequest来发送请求,以及访问navigator的部分属性。

    但是它也存在一些来自浏览器安全沙盒的限制:

    1. 不能加载跨域的JavaScript文件;
    2. 如文件开始所说,考虑到JavaScript操作DOM的安全性问题,在Web Worker中不能访问界面中的DOM信息,对于DOM的访问操作都必须委托给JavaScript主线程来操作;因此HTML5 Web Worker的出现的出现,并没有改变JavaScript单线程执行的这个事实;
    3. 还有就是Web Worker的浏览器兼容性问题。它的浏览器兼容性图如下:

    html5 web worker浏览器兼容性

    更多关于Web Worker的资料,请参考https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers

  • 相关阅读:
    【转】Android WiFi 经常掉线出现的几个原因分析!
    如何分析解决Android ANR
    如何分析和研究Log文件 ,如何看日志信息
    Force removing ActivityRecord no saved state问题的原因分析
    win7下彻底卸载和重装mysql
    mysql的基本操作命令
    mysql 启动,停止,重启
    解决mysql登录报错ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)问题
    一个轻量级的基于 .NET Core 的 ORM 框架 HSQL
    C# ref引用参数与out输出参数的使用与区别
  • 原文地址:https://www.cnblogs.com/yanan-boke/p/8116936.html
Copyright © 2020-2023  润新知