在 angular 应用程序中使用网络工作者(服务工作者在 angular-cli 中缓存数据访问)
Using Webworkers in angular app (service worker cache access of data in angular-cli)
我希望 运行 使用 worker 的功能(在后台)。数据来自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 应用程序创建一个工作者并且没有内存问题。这将是表单提交的用户按钮操作的触发器。
我的问题:
首先,我想知道这是否可以由 service worker 在 Angular 本身中完成,因为它也是一种后台工作线程。
其次,如果不可能,那么我可以从 web worker 访问 service worker 的缓存吗?是否可以访问此服务工作者缓存。这应该怎么做?欢迎任何帮助。
请注意,我可以使用服务工作者,并且可以使用 angular 个服务工作者来缓存所有静态资产。
更新:
我能够使用以下我目前正在处理的配置在 angular 应用程序中启用数据缓存的一些基本想法。
{
"name": "someapi",
"urls": ["/someuri", "/users"],
"cacheConfig": {
"strategy": "freshness",
"maxSize": 20,
"maxAge": "1h",
"timeout": "5s"
}
}
更新:
我能够以粗略的方式完成它并 运行ning 但它有效。将需要 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.
我是这样实现的。我在 angular 中为 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
文件:
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
有资产部分缓存 assets/test.md:
{
"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,但事实并非如此。 service worker 自动从缓存中提供文件(这太棒了)。但是,如果需要访问缓存,我发现可以使用此处的缓存 API 来完成:https://developer.mozilla.org/en-US/docs/Web/API/Cache
我相信可以根据最佳实践改进,并且可以使文件结构更清晰。如果您找到更好的解决方案,请留下答案,以便对大家有所帮助。
是的,这可以由服务人员完成,但是:
如果浏览器认为 service worker 已经完成工作,它可以终止它。因此,请务必将所有内容包装在一个承诺中,并使用 event.waitUntil 确保该过程在完成之前不会终止。
self.addEventListener("message", 函数(事件) {
event.waitUntil(测试(事件));
});
Service Worker 在单个线程上运行,因此如果您执行长时间的同步操作,您的页面的每个请求都会变慢。 Service Worker 不是用来做长计算的。
是的共享工作者可以访问缓存 api。您可以使用全局变量 caches
以与服务工作者相同的方式访问它
caches.open(cacheName).then(function(cache) {
cache.match("...")
});
我希望 运行 使用 worker 的功能(在后台)。数据来自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 应用程序创建一个工作者并且没有内存问题。这将是表单提交的用户按钮操作的触发器。
我的问题:
首先,我想知道这是否可以由 service worker 在 Angular 本身中完成,因为它也是一种后台工作线程。
其次,如果不可能,那么我可以从 web worker 访问 service worker 的缓存吗?是否可以访问此服务工作者缓存。这应该怎么做?欢迎任何帮助。
请注意,我可以使用服务工作者,并且可以使用 angular 个服务工作者来缓存所有静态资产。
更新:
我能够使用以下我目前正在处理的配置在 angular 应用程序中启用数据缓存的一些基本想法。
{
"name": "someapi",
"urls": ["/someuri", "/users"],
"cacheConfig": {
"strategy": "freshness",
"maxSize": 20,
"maxAge": "1h",
"timeout": "5s"
}
}
更新:
我能够以粗略的方式完成它并 运行ning 但它有效。将需要 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.
我是这样实现的。我在 angular 中为 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
文件:
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
有资产部分缓存 assets/test.md:
{
"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,但事实并非如此。 service worker 自动从缓存中提供文件(这太棒了)。但是,如果需要访问缓存,我发现可以使用此处的缓存 API 来完成:https://developer.mozilla.org/en-US/docs/Web/API/Cache
我相信可以根据最佳实践改进,并且可以使文件结构更清晰。如果您找到更好的解决方案,请留下答案,以便对大家有所帮助。
是的,这可以由服务人员完成,但是:
如果浏览器认为 service worker 已经完成工作,它可以终止它。因此,请务必将所有内容包装在一个承诺中,并使用 event.waitUntil 确保该过程在完成之前不会终止。
self.addEventListener("message", 函数(事件) { event.waitUntil(测试(事件)); });
Service Worker 在单个线程上运行,因此如果您执行长时间的同步操作,您的页面的每个请求都会变慢。 Service Worker 不是用来做长计算的。
是的共享工作者可以访问缓存 api。您可以使用全局变量 caches
以与服务工作者相同的方式访问它caches.open(cacheName).then(function(cache) {
cache.match("...")
});