如何在网络工作者中离线访问脚本?

How to access scripts offline in a webworker?

我正在尝试通过使用网络工作者为我们的网络应用程序做一些性能改进。我需要包含一些我使用 importScripts() 的脚本。但难题是 importScripts 在尝试离线访问时失败。如何使用缓存 API 离线访问这些文件?我需要实现自定义 reader 来读取 ReadableStream 吗?是否有更好的标准来实现 Web Worker 内部的离线缓存访问?

详情

这些文件是 javascript 脚本,其中包含一些自定义 js 和外部库,例如 CryptoJS 和 LocalForage。我想实现 - 网络使用 CacheAPI/Service Workers 回退到缓存范例。

我最初实现了一个带有安装和获取事件监听器的标准 Service Worker,但我相信 Service Worker 和 Web Worker 之间的范围是不一样的。在对 MDN 进行一些研究和探索之后,我发现 Cache API 在 WebWorkerScope 中可用,因此我将缓存调用移到了 Web Worker 范围内。

我尝试了多种访问这些文件的方法,包括使用提取事件和仅从缓存中获取文件。在我的 promises 解决后我得到了回复,但回复的主体是一个可读的流,我不确定如何解决这个问题。

任何帮助或指点将不胜感激。

我的网络工作者调用

var worker = new Worker('Path');

我试图按照这篇文章作为指南 - https://developers.google.com/web/ilt/pwa/caching-files-with-service-worker

// Web Worker
self.addEventListener('fetch', function(event){
    event.respondWith(
        fetch(event.request).catch(function(){
            return caches.match(event.request);
        })
    )
});

caches.open('mcaseworker').then(function(cache){
    var urlList = ['/resources/scripts/custom/globalConfig.js',
                    '/resources/scripts/localforage/localforage.min.js'
                    '/resources/scripts/utility/pako.js',
                    '/resources/scripts/cryptojs/aes.js',
                    '/resources/scripts/cryptojs/sha1.js'
                ];
    // Initialize a promise all with the list of urls
    Promise.all(urlList.map(function(url){
        return fetch(url, {
            headers : {
                'Content-Type' : 'application/x-javascript'
            }
        })
        .then(function(response){
            if (response){
                return response;
            }
        });
    }))
    .then(function(values){
        Promise.all(values.map(function(value){
            return value;
        }))
        .then(function(res){
            // Custom Code
            // Would like to access localforage and other javascript libraries. 
        })
    })
})

承诺解决后的响应。

Web workers don't have a fetch event, so your code listening on the fetch event will never trigger. You should put your cache and fetch event listener in a service worker.

主要代码:

if ('serviceWorker' in navigator) {
  // Register a service worker hosted at the root of the
  // site using the default scope.
  navigator.serviceWorker.register('/sw.js').then(function(registration) {
    console.log('Service worker registration succeeded:', registration);
  }, /*catch*/ function(error) {
    console.log('Service worker registration failed:', error);
  });
} else {
  console.log('Service workers are not supported.');
}


const worker = new Worker("/worker.js");

sw.js

self.addEventListener('fetch', function(event){
    event.respondWith(
        fetch(event.request).catch(function(){
            return caches.match(event.request);
        })
    )
});

//Add cache opening code here

worker.js

// Import scripts here
importScripts('/resources/scripts/localforage/localforage.min.js');

您可以查看了解更多关于web worker和service worker的区别