Использование Webworkers в angular app (доступ к кэшу service worker данных в angular-cli)

Я хочу запустить функцию (в фоновом режиме)с помощью рабочего. Данные из HTTP-запроса. Я использую макет расчета (e.data[0] * e.data[1] * xhrData.arr[3]) (заменено функцией, возвращающей фактический результат algo), как показано ниже:

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? и можно ли получить доступ к этому кэшу работник сервиса. Как это сделать? Любая помощь приветствуется.

обратите внимание, что я могу работать с работниками сферы услуг, и я могу кэширование всех статических активов с помощью angular service workers.

обновление:

я смог получить базовую идею включения кэша данных в приложении angular, используя следующую конфигурацию, над которой я сейчас работаю.

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

обновление:

я смог получить это и работать в сырой, но это сработало. Добавлен актив, который нуждался в запросе XHR в ngsw-config.json в разделе Активы. Это кэширует запрос в кэш service worker. Кэш service workers можно открыть с помощью 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 для сервисного работника:

@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 файл в папке assets:

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 был раздел активов, который кэшировал активы / тест.md:

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

из компонента, скажем, например, app.деталь.ts I вызвал 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

Я уверен, что все может быть лучше и структурирование файлов можно сделать более чистым в соответствии с лучшими практиками. Если вы найдете лучшее решение, Пожалуйста, оставьте ответ, чтобы он помог всем.

1 ответов


Да это может быть сделано работником сервиса, но :

  • браузер может завершить работу работника службы, если он считает, что работник службы закончил работу. Поэтому обязательно оберните все внутри обещания и используйте событие.waitUntil, чтобы убедиться, что процесс не завершается до его завершения.

    self.addEventListener ("сообщение", функция (событие) { событие.ждать, пока(испытании(событие)); });

  • работник службы один поток, поэтому, если вы выполняете длительную синхронную операцию, вы замедляете каждый запрос своей страницы. Работники сферы услуг не предназначены для длительных расчетов.

да общие работники могут получить доступ к api кэша. Вы можете получить к нему доступ так же, как и от работника службы, используя глобальную переменную caches

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