CGLib动态代理 自动化部署 tsql cmake Vanilla JS vue响应式 大数据项目开发案例 rxjava线程切换 matlab网页版 hadoop环境变量配置 python安装mysql python例子 java队列 javafile java基础语言 java当前时间 java的map javastring比较 枪神传说辅助 mac画图软件 java电子书 云管家 mssql vs2003 js分页 xflow 算法笔记 mysql导出数据 windowsjs延时函数 pr动态字幕 电脑待机费电吗 光标变粗 服务器下载 套料软件 fla文件用什么打开 思源字体包 c语言小程序 机器人走迷宫 ps文字描边 如何查看路由器密码
当前位置: 首页 > 学习教程  > 编程语言

js中的线程Web Workers

2020/9/19 16:21:54 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除

Web Workers处理线程

概念:在web应用程序中实现后台处理前端逻辑的技术

为什么会有Web Workers处理线程

  1. 在HTML之前的web程序,所有的处理都是在单线程中执行的;
  2. 如果花费时间长,程序界面会一直处于长时间没有响应的状态;
  3. 如果长到一定程度,浏览器会弹出一个提示脚本运行时间过长的提示框;
  4. 用户不得不中断正在执行的处理;

创建Web Workers的方式

index.html:

<script>
    // 注意:后台线程中不可以使用window/document对象
    const worker = new Worker('sumCalculate.js') //传入需要再后台执行脚本的url地址
    // 接受消息
    worker.onmessage = function (e) {
        // 处理接受的消息
        alert('合计值:' + e.data)
    }
    // 发送消息
    function calcute() {
        const num = parseInt(document.getElementById('num').value, 10)
        worker.postMessage(num)
    }
</script>
输入数值:<input type='text' id='num'>
<button onclick='calcute'>计算</button>

sumCalculate.js(后台计算进程):

onmessage = function(e) {
    const num = e.data;
    let result = 0
    for(let i=0;i<= num; i++) {
        result += i
    }
    postMessage(result)
}

线程嵌套

线程可以嵌套子线程,因此比较大的线程可以分成几个子线程,独立完成工作

  1. 主线程代码(index.html)

    <script>
        // 创建线程
        const worker = new Worker('test1.js')
        // 发送信息
        worker.postMessage('')
        // 接受消息
        worker.onmessage = function (e) {
            if (e.data !== '') {
                // 业务逻辑
            }
        }
    </script>
    
    
  2. 子线程1代码(test1.js)

    onmessage = function (e) {
        const intArray = new Array(100)
        for(let i=0; i < 100; i++) {
            intArray[i] = parseInt(Math.random() * 100)
        }
        let worker;
        // 创建子进程2
        worker = new Worker('test2.js')
        // 向子进程2发送数据
        worker.postMessage(JOSN.stringify(intArray))
        worker.onmessage = function (e) {
            postMessage(e.data)
        }
    }
    
  3. 子线程2代码(test2.js)

    onmessage = function (e) {
        const intArray = JSON.parse(e.data)
        let returnStr = ''
         for(let i=0; i < 100; i++) {
             if (parseInt(intArray[i]) % 3 === 0) {
                 if (returnStr != '') {
                     returnStr += ';'
                 }
                 returnStr += intArray[i]
             }
        }
        // 发送消息
        worker.postMessage(returnStr)
        // 关闭进程
        close()
    }
    

线程中可用的变量、函数、类

web workers是属于后台执行前端的js代码,只能使用js中的部分对象和方法

  1. self: 本线程范围内的作用域
  2. postMessage: 用于向线程的源窗口发送信息
  3. onmessage: 获取线程传回来的信息
  4. importScript(urls): 导入其它javascript文件,例如importScript(‘test1.js’,‘test2.js’)
  5. navigator: 和window.navigator一样,具有appName,platform,userAgent,appVersion
  6. sessionStorage/localStorage: 可以使用web Storage
  7. XMLHttpRequest:线程中处理Ajax请求
  8. Web Worker: 创建嵌套线程
  9. setTimeout/setInterval:线程中实现定时处理
  10. close: 结束线程
  11. eval(),isNaN(),escape()等所有js核心函数
  12. object:创建和使用本地对象
  13. WebSockets: 使用WebSockets向服务器发送和接受消息
  14. FileSystem: 在线程中通过同步的FileSystem API实现受沙箱保护的文件系统的文件和目录的创建、更新、删除操作

SharedWorker共享线程

多个页面可以共用一个后台线程,后台线程可以作为一个提供服务的场所

创建线程

//url为后台执行的脚本文件地址,name为指定线程的名称,可选参数
const worker = new ShareWorker(url,[name])

// 单线程/多线程

// worker1和worker2共享一个后天线程
const worker1 = new ShareWorker('test.js')
const worker2 = new ShareWorker('test.js')

// worker1和worker2为两个后台线程
const worker1 = new ShareWorker('test1.js')
const worker2 = new ShareWorker('test2.js')

// worker1和worker2共享一个后天线程
const worker1 = new ShareWorker('test.js', 'nama1')
const worker2 = new ShareWorker('test.js', 'nama1')

// worker1和worker2为两个后台线程
const worker1 = new ShareWorker('test.js', 'nama1')
const worker2 = new ShareWorker('test.js', 'nama2')

前台页面和后台线程通信

// 创建共享进程
const worker1 = new ShareWorker('test.js')
// MessagePort对象
const port = worker1.port
// 向另一个页面发送消息
port.postMessage(message)
port.onmessage = function (e) {
    // 处理收到的信息
}
// 激活端口,开始监听端口是否有接受到信息
port.start()
// 关闭并停用端口
port.close()

// 子进程后台connect对象
onconnect = function (e) {
    // 处理接受的消息
    // 取得页面上的ShareWorker对象的端口
    const port = e.ports[0]
    port.onmessage = function (e) {
        // 向页面返回接受的信息
        port.postMessage(e.data)
    }
}

SharedWorker的使用示例

  1. 单个页面中使用SharedWorker

    主页面代码:

    // 创建共享进程
    const worker1 = new ShareWorker('test.js')
    // MessagePort对象
    const port = worker1.port
    // 向另一个页面发送消息
    port.start()
    port.postMessage(message)
    port.onmessage = function (e) {
        // 处理收到的信息
    }
    

    进程test.js代码:

    // 子进程后台connect对象
    onconnect = function (e) {
        // 处理接受的消息
        // 取得页面上的ShareWorker对象的端口
        const port = e.ports[0]
        port.onmessage = function (e) {
            // 向页面返回接受的信息
            port.postMessage('ninhao')
        }
    }
    
  2. 多个页面中使用SharedWorker

    第一个页面代码:

    // 创建共享进程
    const worker1 = new ShareWorker('test1.js')
    // MessagePort对象
    const port = worker1.port
    port.start()
    // 向另一个页面发送消息
    port.postMessage(1)
    port.onmessage = function (e) {
        // 处理收到的信息
    }
    

    第二个页面代码:

    // 创建共享进程
    const worker1 = new ShareWorker('test1.js')
    // MessagePort对象
    const port = worker1.port
    // 向另一个页面发送消息
    port.start()
    port.postMessage(2)
    port.onmessage = function (e) {
        // 处理收到的信息
    }
    

    进程test1.js代码:

    // 子进程后台connect对象
    onconnect = function (e) {
        // 处理接受的消息
        // 取得页面上的ShareWorker对象的端口
        const port = e.ports[0]
        port.onmessage = function (e) {
            // 向页面返回接受的信息
            port.postMessage(e.data * e.data)
        }
    }
    

本文链接: http://www.dtmao.cc/news_show_200401.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?