在角度app中使用Webworkers(angular-cli中的数据的服务工作者缓存访问) [英] Using Webworkers in angular app (service worker cache access of data in angular-cli)

查看:73
本文介绍了在角度app中使用Webworkers(angular-cli中的数据的服务工作者缓存访问)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I wish to run an function (in the background) using a worker. The data comes from a http request. I am using a mock calculation (e.data[0] * e.data[1] * xhrData.arr[3]) (replaced by a function returning the actual algo result) as below:

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实现。我计划使用一个服务(加上一个共享工作者),所以我每个角度应用程序只创建一个工作者,没有内存问题。这将是表单提交的用户按钮操作的触发器。

This works fine. But, this is a pure JS implementation. I was planning to use a service (plus a shared worker) for this so I create only one worker per angular app and dont have memory issues. This is going to be a trigger from a user button action of form submit.

我的问题:

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

First, I am wondering if this can be done by service workers in Angular itself since it is also a type of background worker thread.

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

Second, If not possible then can I access the cache of service workers from web worker? and Is it possible to access this service worker cache. How is this supposed to be done? Any help is welcome.

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

Note that I am able to work with service workers and I am able to cache all static assets using angular service workers.

我能够使用以下配置获取角度应用程序中启用数据缓存的基本概念,我目前正在使用on。

I was able to get some basic idea of enabling data cache in the angular app using following config which I am currently working on.

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



< h2>更新:

我能够在原油中运行并运行但是它有效。将需要XHR请求的资产添加到资产部分的ngsw-config.json中。这会将请求缓存到服务工作缓存中。可以使用 caches.open('ngsw:db:$ {name}')打开服务工作者缓存,但我不必这样做。

Update:

I was able to get this up and running in a crude but it worked. Added the asset that needed the XHR request into the ngsw-config.json in the assets section. This cached the request into service worker cache. The service workers cache can be opened using caches.open('ngsw:db:${name}') but I did not have to do that.

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.

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

Here is how I achieved that. I created a service in angular for the service worker:

@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);
      }
  }

}

然后我在assets文件夹中创建了一个 web-worker.js 文件:

Then I created a web-worker.js file in the assets folder:

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);
};

我的 ngsw-config.json 有资产缓存资产/ test.md的部分:

My ngsw-config.json had assets section which cached assets/test.md:

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

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

From the component, say for example, app.component.ts I triggered a 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');
  }

}

这使得网络工作者。 js触发XHR请求。虽然我期待我将不得不使用缓存访问api我自己,但事实并非如此。服务工作者自动从缓存中提供文件(这太棒了)。但是,如果需要访问缓存,我​​发现可以使用缓存API在此处完成: https://developer.mozilla.org/en-US/docs/Web/API/Cache

This makes the web-worker.js trigger the XHR request. Though I was expecting I will have to use a cache access api my self, it was not so. The service worker automatically served the file from the cache (Which is fantastic). However if there is a need to access the cache I found this can be done using the cache API here: https://developer.mozilla.org/en-US/docs/Web/API/Cache

我确定的事情根据最佳实践,可以使文件结构更清晰。如果你找到一个更好的解决方案请留下答案,这样可以帮助每个人。

I am sure things can be bettered and file structuring can be made cleaner as per best practices. If you find a better solution please leave an answer so it helps everyone.

推荐答案

是的,这可以由服务工作者完成,但是:

Yes this can be done by a service worker but :


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

  • The browser can terminate a service worker if it thinks the service worker has finished working. So be sure to wrap everything inside a promise and use event.waitUntil to make sure that the process isn't terminated before it has finished.

self.addEventListener(message ,function(event){
event.waitUntil(test(event));
});

self.addEventListener("message", function(event) { event.waitUntil(test(event)); });

服务工作者运行在一个线程上,所以如果你进行长时间的同步操作,你会减慢页面的每个请求。服务工作者不打算进行长时间的计算。

The service worker runs on a single thread, so if you do long synchronous operation you'd be slowing every request of your page. Service workers are not meant to do long calculation.

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

Yes shared workers can access the cache api. You can access it the same way you do from a service worker by using the global variable caches

caches.open(cacheName).then(function(cache) {
      cache.match("...")
});

这篇关于在角度app中使用Webworkers(angular-cli中的数据的服务工作者缓存访问)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆