在 Angular 应用程序中使用 WebWorkers(服务工作线程缓存 Angular-CLI 中数据的访问)

2023-11-21

我希望使用工作人员运行一个函数(在后台)。数据来自http请求。我正在使用模拟计算(e.data[0] * e.data[1] * xhrData.arr[3])(由返回实际算法结果的函数替换)如下:

var ajax =  function() {
    var prom = new Promise(function(resolve, reject){
        if (!!XMLHttpRequest) {
            var xhttp = new XMLHttpRequest();
            xhttp.onload = function () {
                if (this.readyState == 4 && this.status == 200) {
                    resolve(JSON.parse(this.responseText));
                }
            };
       // Cache Logic - Will be adding logic to check cache 
       // if test.json is in cache.
       // If it is then fetch res from cache
       // There will be multiple XHR requests in parallel, not one
            xhttp.open("GET", "test.json", true);
            xhttp.send();
        }
    });
    return prom;
}

async function test (e) {
    var workerResult, xhrData;
   try {
    xhrData  = await ajax();
    workerResult = (e.data[0] * e.data[1] * xhrData.arr[3]);
    postMessage({res: workerResult});
   } catch(err) {
    postMessage({err: 'Failed'});
   }
}

onmessage = function (e) {
    test(e);
};

这很好用。但是,这是一个纯 JS 实现。我计划为此使用一项服务(加上共享工作人员),因此我每个角度应用程序仅创建一个工作人员,并且不会出现内存问题。这将是表单提交的用户按钮操作的触发器。

我的问题:

首先,我想知道这是否可以由 Angular 本身的服务工作线程来完成,因为它也是一种后台工作线程。

其次,如果不可能,那么我可以从 Web Worker 访问 Service Worker 的缓存吗?以及是否可以访问此服务工作线程缓存。这应该怎么做?欢迎任何帮助。

请注意,我能够与服务工作人员一起工作,并且能够使用角度服务工作人员缓存所有静态资产。

Update:

我能够使用我当前正在处理的以下配置获得在角度应用程序中启用数据缓存的一些基本想法。

{
    "name": "someapi",
    "urls": ["/someuri", "/users"],
    "cacheConfig": {
      "strategy": "freshness",
      "maxSize": 20,
      "maxAge": "1h",
      "timeout": "5s"
    }
  }

Update:

我能够以粗略的方式启动并运行它,但它有效。将需要 XHR 请求的资产添加到资产部分的 ngsw-config.json 中。这会将请求缓存到服务工作线程缓存中。可以使用以下命令打开服务工作者缓存caches.open('ngsw:db:${name}')但我不必那么做。

I created a web worker file inside the assets folder
The XHR request was made in it. 
When a XHR was made the service worker automatically picked up the cache
So I did not have to use any alternate methods of cache access.
Sworkers was automatically served the XHR request from the cache.

这是我实现这一目标的方法。我为服务工作者创建了一个角度服务:

@Injectable({
  providedIn: 'root'
})
export class WebworkerService {
  myWorker: any;
  constructor() {
      this.myWorker = new Worker('/assets/web-worker.js');
      this.myWorker.onmessage = function(data) {
        console.log(data);
      }
  }

}

然后我创建了一个web-worker.js资产文件夹中的文件:

var ajax =  function() {
    var prom = new Promise(function(resolve, reject){
        if (!!XMLHttpRequest) {
            var xhttp = new XMLHttpRequest();
            xhttp.onload = function () {
                if (this.readyState == 4 && this.status == 200) {
                    resolve(this.responseText);
                }
            };
            xhttp.open("GET", "/assets/test.md", true);
            xhttp.send();
        }
    });
    return prom;
}

async function test (e) {
    var workerResult, xhrData;
   try {
    xhrData  = await ajax();
    workerResult = xhrData; // Some calculation or activity here
    postMessage({res: workerResult});
   } catch(err) {
    postMessage({err: 'Failed'});
   }
}

onmessage = function (e) {
    test(e);
};

My ngsw-config.json有缓存 asset/test.md 的 asset 部分:

{
    "name": "assets",
    "installMode": "lazy",
    "updateMode": "prefetch",
    "resources": {
      "files": [
        "/assets/**"
      ]
    }
  }

从组件中,例如 app.component.ts 我触发了 postMessage()

@Component({
  selector: 'app-root',
  template:`
 <h1 (click)="myHttp()">
    Some Client Event
  </h1>
`,
  styleUrls: ['./app.component.css'],
  providers: []
})
export class AppComponent {
  constructor(private _ww: WebworkerService) { }
  myHttp() {
    this._ww.myWorker.postMessage('Test');
  }

}

这使得 web-worker.js 触发 XHR 请求。虽然我原以为我必须自己使用缓存访问 api,但事实并非如此。服务工作线程自动从缓存中提供文件(这太棒了)。但是,如果需要访问缓存,我​​发现可以使用此处的缓存 API 来完成:https://developer.mozilla.org/en-US/docs/Web/API/Cache

我相信事情可以得到改善,文件结构可以根据最佳实践变得更清晰。如果您找到更好的解决方案,请留下答案,以便对大家有所帮助。


是的,这可以由服务人员完成,但是:

  • 如果浏览器认为 Service Worker 已完成工作,则可以终止该 Service Worker。因此,请务必将所有内容包装在 Promise 中,并使用 event.waitUntil 来确保进程在完成之前不会终止。

    self.addEventListener("消息", 函数(事件) { event.waitUntil(测试(事件)); });

  • 服务工作线程在单个线程上运行,因此如果您执行长时间同步操作,则会减慢页面的每个请求。 Service Worker 不适合进行长时间的计算。

是的,共享工作人员可以访问缓存 api。您可以使用全局变量缓存以与服务工作者相同的方式访问它

caches.open(cacheName).then(function(cache) {
      cache.match("...")
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Angular 应用程序中使用 WebWorkers(服务工作线程缓存 Angular-CLI 中数据的访问) 的相关文章

  • Google Maps API v3:在 Firefox 中未触发自定义标记的点击事件

    创建了一个地图 我试图使其具有类似于 我的地图 的功能 我的右侧有两个下拉列表 根据这些 ddl 中的选择 您可以添加自定义标记 图标 您选择标记类型 然后单击地图右上角的 按钮 然后单击要添加标记的位置 我的问题是 这在 IE Safar
  • 使用 jest 测试 catch 块

    我如何测试下面我使用类的代码片段中的 catch 块 示例 js class Sample constructor data this resolvedData this retrieveData data retrieveData dat
  • “mat-card” 不是 Angular 7 中的已知元素

    我看到了很多关于此的问题 但似乎与我遇到的问题不同 我刚刚创建了我的第二个角度项目 我下面有一个新组件src app employees我试图在employees component html 中使用 我收到的错误是 Uncaught Er
  • firebug 打开后断点重复触发

    当我在一个站点上打开 firebug 时 我无法分析任何内容 因为每隔几秒就会在该行上触发一个断点 function function a try function b i if i i length 1 i 20 0 function c
  • 如何在严格模式下设置元素样式属性?

    Given body document getElementsByTagName body 0 iframe document createElement iframe iframe src protocol settings script
  • 单击链接时如何将另一个 JSP 页面注入到

    我在一个JSP页面中有两个不同的部分 其中一个包含链接菜单 单击时 div2 id content 会相应加载不同的页面 我正在做类似的事情 div ul class navbar li a href Login jsp Login a l
  • 是否可以加载本地版本的 JavaScript 文件而不是服务器版本?

    只是有一个简单的问题要抛出 看看是否有解决方案 假设我无法访问服务器 我加载一个网页 发现他们有一个从子文件夹加载的 Javascript 文件 比方说 scripts js some js 现在 我想在本地对此文件进行更改 并针对整个站点
  • 解密签名并验证 JWT

    我知道还有其他库可以让我更轻松地使用 JWT 在 Node js 中 在本例中 我使用 crypto js 以手动方式学习 JWT 以下给了我令牌 var header alg HS256 typ JWT var wordArrayHead
  • 如何编写具有依赖状态的 redux 减速器

    我正在开发一个 React Redux 应用程序 它允许将 小部件 添加到页面并在 2D 空间中进行操作 要求可以同时选择和操作多个小部件 我当前状态树的简化版本如下所示 widgets widget 1 x 100 y 200 widge
  • Django CBV表单提交返回的JSON显示为新页面

    我正在使用 Django 3 2 我正在创建一个简单的时事通讯订阅表格 表单提交将 JSON 返回到前端 然后应该使用前端来更新页面的部分内容 但是 当我发布表单时 JSON 字符串将在新页面上显示为文本 这是调用视图的路由 urlpatt
  • 如何在cypress测试中实现拖放?

    我正在努力测试拖放Cypress https www cypress io and 角度材质拖放 https material angular io cdk drag drop overview 因此 我们的目标是将 开始工作 从 待办事项
  • 缩放对象上的弹跳动画

    拥有对象比例 然后在返回到原始比例因子之前以该比例因子执行弹跳动画的最佳方法是什么 我意识到我可以做一些事情 比如将其缩放到 2 2 然后 1 8 然后 2 0 但我正在寻找一种方法 您只需在比例因子上执行弹跳动画 因为我的比例因子会改变
  • 将 Blob 设置为 iframe 的“src”

    以下代码在 Chrome 中完美运行 但它不适用于 IE 有人可以告诉我这里出了什么问题吗 iframe src 也设置为 blob 如下所示
  • 如何沿着 Parse Promise 链传递额外数据[重复]

    这个问题在这里已经有答案了 在我的 Parse Cloude 代码中 我需要运行几个连续的查询 每个查询都使用 find Example var promise firstQuery get objectId then function r
  • 如何使用 angular2 的路由器实现面包屑[重复]

    这个问题在这里已经有答案了 I use angular2最近 但不知道如何实施breadcrumb组件 任何人都可以帮忙吗 div class row style padding top 15px ol class breadcrumb l
  • 手动刷新 Angular 之前页面无法正常显示

    我面临着非常奇怪的问题 我的角度应用程序页面显示正确 它似乎没有完全加载 当我手动重新加载 刷新页面时 它的加载正常 这是完整的场景 我创建了一个登录页面 该页面显示完美并按预期工作 登录后 我导航到仪表板页面 该页面未正确显示 似乎加载了
  • 使用 Javascript 编辑和保存用户 HTML - 安全性如何?

    例如我有一个Javascript 支持的表单创建工具 您可以使用链接添加元素的 html 块 如输入字段 并使用 TinyMCE 来编辑文本 这些是通过自动保存功能保存的 该功能在特定事件的后台执行 AJAX 调用 被调用的保存函数负责数据
  • PhoneGap文件传输错误1、哪里写FileTransfers?

    相关 https stackoverflow com questions 21044197 download file and store them locally in sdcard using phonegapbuild https s
  • 将 ERB 与 Handlebars 模板结合使用

    我有一个使用 ajax 创建新标签的模式 它使用 Tags 参数执行 POST 方法 而无需重新充电视图 因此 我希望根据所选的 price type 参数来呈现一个或另一个价格 div 我使用 Handlebars 所以我想这不是 rub
  • 如何在JAVascript中删除具有相同ID但display='block'和display='none'的div

    我有超过 1 个 div 具有相同的 id 但其中一个具有 display block 和其他人有显示 无 我想删除所有具有 display none 的 div 请告诉最简单的方法 文档中多个元素具有相同的 id 是违反 W3 标准的 请

随机推荐