3

Возможно ли, чтобы работники службы подождали, чтобы начать обработку событий выборки, пока асинхронная работа не завершится при запуске сервисного персонала?Есть ли запуск рабочего рабочего ServiceUntil для отсрочки обработки?

У меня есть оболочка приложения с маршрутами, определенными в данных. Чтобы установить определенные обработчики выборки маршрутов при запуске сервисного персонала, мне нужно искать данные маршрута из IndexedDB (асинхронно).

К сожалению, рабочий сервис начинает принимать события выборки до того, как поиск IndexedDB может завершить и настроить обработку выборки для маршрутов.

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

Я не видел способ «waitUntil» для этого, возможно, я пропустил его?

ответ

3

Существует обходной путь:

function startupAsyncStuff() { 
    return new Promise(function (fulfill, reject) { 
    // put here your async stuff and fulfill the promise when done. 
    }); 
} 

// Launch your startup async code 
var asyncStuffDone = startupAsyncStuff(); 

// On fetch, wait for the former promise to be resolved first 
self.onfetch = function (event) { 
    event.respondWith(asyncStuffDone.then(function() { 
    // your fetch handling code 
    })); 
}; 
+0

Это хороший, общий пример демонстрации правильного ответа. Благодаря! –

+0

Прошу прощения, этот кодекс с обещаниями все еще новен. Как вы «выполняете обещание, когда делаете»? И каков параметр «reject» для. Спасибо за ваше терпение моим вопросом noob (: –

6

Фрагмент кода поможет, как я не на 100% ясно по этому вопросу ... Но сделать несколько предположений:

Пока вы не решить обещание, предоставленное event.waitUntil, когда вы выслушали для установки события , SW не должен перехватывать какие-либо сетевые запросы, поэтому создание IDB там должно быть прекрасным.

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

В целом также стоит обратить внимание на то, что SW могут и часто убивать, поэтому локальные переменные не будут помещаться между получением разных событий. Если вам нужны данные, которые вам понадобятся при работе с другим событием, вы должны сохранить его в IDB или API-интерфейсе Cache и снова получить его оттуда.

+0

Где находится Event.waitUntil для запуска? Моя ситуация возникает после того, как SW был убит и снова начинает обслуживать страницу. –

+1

Ах, я предполагал, что проблема была в ожидании после установки, причем не каждый раз, когда она запускается. Если проблема заключается в том, что вам нужно выполнить поиск IDB после запуска, но прежде, чем маршрутизировать извлеченные вами выборки, вы должны иметь возможность вызвать e.waitUntil в прослушивателе выборки и передать обещание, которое разрешается после того, как вы создали ответ, часть которого будет включать поиск ИБР. Дайте мне знать, если я все еще недопонимаю, с удовольствием рассмотрю фрагмент кода :) – owencm

+0

У вас его сейчас - вот в чем проблема. Похоже, что решение IS для добавления обработчика выборки для этого и waitUntil. У меня нет «фрагмента» для этого, но храбрый/любопытный может видеть [код] (https://github.com/localnerve/flux-react-example-sw/tree/master/assets/scripts/ ЕО). Две проблемы с этим ** 1. ** Вспышка «offline dino» при запуске, когда процесс sw еще не запущен, [ссылка] (http://stackoverflow.com/questions/33906701/what-is-the-expected -startup-experience-for-a-progressive-web-application) ** 2. ** Задержка под ложью-fi, поскольку бесполезная непроверенная выборка проходит через сеть. –

0

Поскольку я использовал SW-инструментов и выполнения асинхронной работы при запуске, что обработчики установки маршрута, лучшее решение для меня было определить временную SW-панели инструментов по умолчанию до тех пор, пока обработчики не будут готовы ответить.

var toolbox = require('sw-toolbox'); 

var setupPromise = someAsyncHandlerSetup() 
.then(function() { 
    // make default handler temporary, allows other fetch handlers. 
    toolbox.router.default = null; 
}); 

// until the async handler setup is done, provide a default handler 
// to avoid an offline-dino flash when starting up while offline. 
toolbox.router.default = function defaultHandler (request) { 
    return setupPromise.then(function() { 
    var handler = toolbox.router.match(request); 
    if (handler) { 
     return handler(request); 
    } 
    throw new Error('default handler could not handle ' + request.url); 
    }); 
};