广告位联系
返回顶部
分享到

在web worker中使用fetch实例介绍

JavaScript 来源:互联网 作者:佚名 发布时间:2022-11-17 22:08:45 人浏览
摘要

1.Web Worker意义 由于 JS 是单线程的,费时的 JS 操作将会导致整个页面的阻塞。Web Worker 提供了创建多线程的方法,将一些耗时且 UI 无关的工作交给 worker,可提高页面的使用体验。 限制

1.Web Worker意义

由于 JS 是单线程的,费时的 JS 操作将会导致整个页面的阻塞。Web Worker 提供了创建多线程的方法,将一些耗时且 UI 无关的工作交给 worker,可提高页面的使用体验。

限制:

同源策略:worker 线程执行的脚本要和当前页面同源

API 限制:

  • 不能操作 DOM
  • 不能使用 window 的全局变量,但可以使用 navigator 和 location 对象
  • 不能使用 alert、confirm 方法
  • 无法读取本地文件

和主线程不在一个上下文环境,通讯要通过 postMessage 完成

2. 主线程的使用

创建

创建一个子线程,要传入一个脚本的 URL。如果该脚本加载失败,则 Worker 会静默失败

1

const worker = new Worker('url');

如果要在本文件中描述执行的内容,可以用 Blob 和 window.URL.createObjectURL 生成一个 URL

1

2

3

4

5

6

function createWorker(f) {

  const blob = new Blob(['(' + f.toString() +')()']);

  const url = window.URL.createObjectURL(blob);

  const worker = new Worker(url);

  return worker;

}

通信

  • 主线程 => 子线程

1

worker.postMessage(param);

参数可以是任意类型,包括二进制数据。但传递是拷贝形式而不是引用形式。因此对于大数据会存在性能问题。

  • 子线程 => 主线程

1

2

3

worker.onmessage = function (event) {

  console.log('Received message ' + event.data);

}

错误处理

1

2

3

4

5

worker.onerror(function (e) {

  console.log([

    'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message

  ].join(''));

});

关闭

1

worker.terminate();

3. 子线程的使用

子线程中无法使用 window,self 代表全局对象

和主线程的通信

  • 主线程 => 子线程

1

2

3

self.addEventListener('message', function (e) {

  self.postMessage('Received: ' + e.data);

}, false);

  • 子线程 => 主线程

1

self.postMessage('something');

加载其他脚本

在子线程中加载其他脚本:

1

importScripts('script1.js', 'script2.js');

关闭

1

self.close();

4. 在WebWorker中使用fetch

网络请求是和DOM无关且可能耗时较长的操作,worker线程支持使用Fetch,是适合放在worker中进行的操作。

而要在worker中使用fetch,如果每次都要自己处理线程间的通信的话,会十分麻烦,因此我对通信进行了封装,写成了一个可以直接使用的库。

安装依赖:

1

npm i web-worker-fetch

使用时先实例化一个WF对象,然后就可以像使用fetch一样在worker中使用fetch:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

import WebWorkerFetch from "web-worker-fetch";

const wf = new WebWorkerFetch();

wf.fetch("url", {

  method: "POST", // *GET, POST, PUT, DELETE, etc.

  mode: "cors", // no-cors, *cors, same-origin

  cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached

  credentials: "same-origin", // include, *same-origin, omit

  headers: {

    "Content-Type": "application/json"

    // 'Content-Type': 'application/x-www-form-urlencoded',

  },

  redirect: "follow", // manual, *follow, error

  referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url

  body: JSON.stringify(data) // body data type must match "Content-Type" header

}).then((res) => console.log(res));

除此之外,借鉴 axios 的思路,配置中可以提供 requestInterceptor 和 responseInterceptor,对请求参数和返回数据做统一处理

5. 实现思路

这个库的封装主要是解决了两个问题:

  • 发送请求时如何把参数传递给worker线程
  • 请求结束后如何从worker线程获取结果

对于第一个问题,主线程使用 ostMessage 向worker线程传递参数。

对于第二个问题,worker线程通过 self.postMessage 向主线程传递消息,主线程通过 worker.onmessage 监听消息。

此时就引出了问题所在:如果多次使用 wf.fetch 发送请求,那么在一个请求完成后,worker线程触发的消息将让所有请求处都认为请求已完成。

因此,在每次请求时,使用一个fetchId确定该请求做唯一性。将该id传给worker线程,后续worker线程向主线程通信时也会带上这个id。

在主线程中监听onmessage事件时,判断id是否和自己的请求id一致,只有在相同时才做处理。

具体的实现大家可以移步仓库源码,实际上也非常简单。


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://juejin.cn/post/7165864211447939102
相关文章
  • Vue屏幕自适应三种实现方法介绍
    使用 scale-box 组件 属性: width宽度 默认1920 height高度 默认1080 bgc背景颜色 默认transparent delay自适应缩放防抖延迟时间(ms) 默认100 vue2版本:
  • 在web worker中使用fetch实例介绍
    1.Web Worker意义 由于 JS 是单线程的,费时的 JS 操作将会导致整个页面的阻塞。Web Worker 提供了创建多线程的方法,将一些耗时且 UI 无关的工
  • 实时通信Socket io的使用介绍

    实时通信Socket io的使用介绍
    最近在工作中,遇到了一个需求,需要和后台服务实时通信,获取各种设备的实时状态、以及对设备下发指令。后端这边选择了socket.io这个
  • js中如何对url进行编码和解码
    js 对url进行编码和解码 三种编码和解码函数 encodeURI和 decodeURI 它着眼于对整个URL进行编码,因此除了常见的符号以外,对其他一些在网址中
  • React RenderProps模式超详细介绍
    render prop是一个技术概念。它指的是使用值为function类型的prop来实现React component之间的代码共享。 如果一个组件有一个render属性,并且这个
  • Vue中ref、reactive、toRef、toRefs、$refs的基本用法总

    Vue中ref、reactive、toRef、toRefs、$refs的基本用法总
    一、ref reactive 1.1.为什么需要ref、reactive ??? setup函数中默认定义的变量并不是响应式的(即数据变了以后页面不会跟着变),如果想让变量变
  • Javascript如何实现对象扁平化实例介绍

    Javascript如何实现对象扁平化实例介绍
    数组扁平化相信大家已经耳熟能详了,在被面试官问到如何实现数组扁平化你就偷着乐吧,但是相信有不少大佬在面试一些国内顶尖的大厂
  • Immer功能最佳实践示例教程

    Immer功能最佳实践示例教程
    一、前言 Immer 是mobx的作者写的一个 immutable 库,核心实现是利用 ES6 的 proxy,几乎以最小的成本实现了 js 的不可变数据结构,简单易用、体
  • Ant Design 的Bug修复示例
    我在工作中大量使用Ant Design,它为我省去了很多重复劳动,所以有空的时候,我也会为Ant Design做一些微小的贡献。 本文详细描述了我处理
  • AntDesignPro使用electron构建桌面应用示例
    注意事项声明 所有node包必须使用npm安装不可使用cnpm, 使用cnpm安装的node包会导致打包时间无限可能 具体区别查看使用npm和cnpm安装的包结构
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计