服务工作者和承诺:没有返回正确的答复

Dea*_*ano 2 javascript es6-promise service-worker progressive-web-apps

在Service Worker中,我使用以下代码来测试外部JavaScript文件是否需要超过500毫秒才能返回.下面的代码也使用Promise竞争条件来确定网络是更快还是超时.如果超时获胜,那么我希望返回408响应.

function timeout(delay) {
    return new Promise(function(resolve, reject) {
        setTimeout(function(){
          new Response('', {
              status: 408,
              statusText: 'Request timed out.'
          });
        }, delay);
    });
}

self.addEventListener('fetch', function(event) {
    // Only fetch JavaScript files for now
    if (/\.js$/.test(event.request.url)) {
      event.respondWith(Promise.race([timeout(500), fetch(event.request.url)]));
    } else {
      event.respondWith(fetch(event.request));
    }
});
Run Code Online (Sandbox Code Playgroud)

我通过使用开发工具限制网络连接并强制它花费超过设置的500毫秒来测试这一点.

Chrome开发工具

超时每次都会赢,并记录到控制台,这正是我所期望的.但是,它没有按预期返回408,而是返回200.任何想法?

你可以在Github上看到一个这样的例子:https: //deanhume.github.io/Service-Workers-Fetch-Timeout/

和来源:

https://github.com/deanhume/Service-Workers-Fetch-Timeout/blob/gh-pages/service-worker.js

Fra*_*ano 5

你需要event.respondWith在promise中执行:

(没有尝试这个代码,只是在运行中)

function timeout(delay) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
          resolve(new Response('', {
              status: 408,
              statusText: 'Request timed out.'
          }));
        }, delay);
    });
}

self.addEventListener('fetch', function(event) {
    // Only fetch JavaScript files for now
    if (/\.js$/.test(event.request.url)) {
      event.respondWith(Promise.race([timeout(500), fetch(event.request.url)]);
    } else {
      event.respondWith(fetch(event.request));
    }
});
Run Code Online (Sandbox Code Playgroud)

还修改了timeout函数以返回响应,因此Promise.race将返回一个Response对象.