2015-09-08 2 views
4

Мне нужно послать серию PUT & POST-запросов от Service Worker. Порядок, в котором они отправлены, имеет значение.Синхронная или последовательная выборка в обслуживающем работнике

Требования:

  • Данный метод запроса, URL и JSON тело, отправить запрос
  • Если это удастся (response.status < 300):
    • Pass тела к функции успеха
    • Вызвать следующий запрос в очереди
  • Если это не удается:
    • Pass responseText или заблуждаться ошибки функции исполнения
    • Stop

Если я просто перебирать очереди и вызвать fetch для каждого запроса, сеть дисперсия может (часто делает) вызывает запросы чтобы выйти на сервер не по порядку.

Как создать цепочку из fetch запросов, где каждый результат зависит от успеха предыдущего?


Что я пробовал:

  • XHR вместо (предполагая, что я мог бы использовать "асинхронной ложь", но это не допускается в службе работника).
  • setTimeout(sendRequest, i*200). Взлом, не надежный.
  • Promise loops Основано на данных примерах ES6 Promise Patterns. Это казалось наиболее перспективным, но примеры для простого случая, когда предполагается успех. Не удается заставить его работать с извлечением.

Контекст: Я использую «Исходящие» запросов API для поддержки чтения в автономном режиме, создание и обновление данных. Хорошо работает, за исключением этой проблемы с заказом.

+0

Примечания: Я использую родные Обещания ES6, в то время как «дублировать» вопрос относится к другим библиотекам. – AdrianoFerrari

ответ

1

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

var workQueue = [work, goes, here]; 
var currentItem = workQueue.shift(); 
return performWorkWith(currentItem) 
     .then(handleResponseWithQueue(workQueue)); 

function handleResponseWithQueue(queue) { 
    return function handleResponse(response) { 
     if (response.ok && queue.length > 0) 
     return performWorkWith(queue.shift()).then(handleResponseWithQueue(queue)); 
    }; 
} 

Вы можете обобщить эту картину в (упрощенно):

function series(work, queue) { 
    if (queue.length <= 0) return; 
    work(queue.shift()).then(function() { 
    if (queue.length > 0) return series(work, queue); 
    }); 
} 
+0

Спасибо @ sean-vieira! Оказывается, я был настолько доволен своим замешательством в отношении обещаний, что я не убедился, что сама очередь очищается, поскольку она была обработана. – AdrianoFerrari

3

Я думаю, что вы будете хотеть следовать Sync loop шаблон из этой ES6 Promise Patterns страницы.

После того, как ваша цепочка обещаний «успех» настроена через .reduce(), вы можете прикрепить к концу один пункт .catch(), чтобы обрабатывать отчет об ошибках. Любое отклонение обещания/throw внутри цепочки обещаний будет замыкаться на все .then() и спрыгнуть прямо к вашему .catch() в конце.

Для того, чтобы это работало, как вы описали, вы хотите явно проверить статус ответа на ошибку HTTP в вашем fetch(...).then(...) и throw, если вы столкнулись с одним, так как реакция на ошибку HTTP не будет в противном случае вызвать .catch(). (NetworkError s или подобные исключения во время выполнения будет запускают .catch(), хотя.) Что-то вроде:

fetch('https://example.com').then(response => { 
    if (!response.ok) { // See https://fetch.spec.whatwg.org/#ok-status 
    throw new Error('Invalid HTTP response: ' + response.status); 
    } 
    // Otherwise, do something with the valid response. 
}) 
+0

Спасибо за это, @ jeff-posnick. Я не понимал, что я не ошибся, так что это было частью проблемы. Тем не менее, я отметил другой, поскольку большая проблема заключалась в том, что я сам не очищал очередь! – AdrianoFerrari

 Смежные вопросы

  • Нет связанных вопросов^_^