js中的线程Web Workers

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)
        }
    }
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值