繁体   English   中英

在角度app中使用Webworkers(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本身的服务工作者完成,因为它也是一种后台工作者线程。

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

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

更新:

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

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

更新:

我能够在原油中运行并运行但是它有效。 将需要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);
      }
  }

}

然后我在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我自己,但事实并非如此。 服务工作者自动从缓存中提供文件(这太棒了)。 但是,如果需要访问缓存,我​​发现可以使用缓存API在这里完成: https//developer.mozilla.org/en-US/docs/Web/API/Cache

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

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM