2

В 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)); 
    } 
}); 

Я тестирую это, регулируя сетевое подключение с помощью инструментов dev и заставляя его занимать больше времени, чем установленные 500 мс.

Chrome Dev Tools

Тайм-аут выигрывает каждый раз и журналы на консоли, которая является именно то, что я хотел бы ожидать. Однако он не возвращает 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

ответ

5

Вы должны выполнить event.respondWith не в обещании:

(не пробовал этот код, просто делал это на лету)

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)); 
    } 
}); 

Также была изменена функция timeout, чтобы вернуть ответ, поэтому Promise.race вернет объект Response.

+0

Я уточнил вопрос соответственно .... – Deano

+0

Это было исправление - спасибо! – Deano

+1

Обратите внимание, что 'event.respondWith (fetch (event.request));' в разделе 'else {}' не требуется. Если вы оставите вызов 'event.respondWith()', тогда нормальный сетевой запрос/поток ответов все равно будет иметь место, без участия какого-либо сотрудника службы. –