服务工作者中的同步或顺序提取

时间:2015-09-08 14:15:37

标签: javascript promise es6-promise service-worker

我需要发送一系列PUT&来自服务工作者的POST请求。他们发送的顺序很重要。

要求:

  • 给定请求方法,网址和JSON正文,发送请求
  • 如果成功(response.status < 300):
    • 将正文传递给成功函数
    • 在队列中调用下一个请求
  • 如果失败:
    • 将responseText或err传递给错误函数
    • 停止执行

如果我只是遍历队列并为每个请求调用fetch,网络差异可能(通常会)导致请求无序到达服务器。

如何制作一系列fetch请求,其中每个结果取决于前一个请求的成功?

我尝试过的事情:

  • XHR(假设我可以使用&#34; async:false&#34;,但服务工作者不允许这样做。)
  • setTimeout(sendRequest, i*200)。黑客,不可靠。
  • Promise loops基于这些示例ES6 Promise Patterns。这似乎是最有希望的,但这些例子是假设成功的简单案例。无法使用fetch。

上下文:我正在使用&#34;发件箱&#34; API请求支持离线阅读,创建和更新数据。除了这个订购问题外,效果很好。

2 个答案:

答案 0 :(得分:3)

不是立即将队列中的每个请求转换为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);
  });
}

答案 1 :(得分:3)

我认为您希望遵循该Sync loop页面中的ES6 Promise Patterns模式。

通过.reduce()设置“成功”承诺链后,您可以在末尾附加单个.catch()子句来处理错误报告。承诺链中的任何承诺拒绝/ throw都会使所有.then()短路,并在最后直接跳转至.catch()

为了使其按照您的描述工作,您需要明确检查fetch(...).then(...)throw中的错误HTTP响应状态(如果遇到),因为HTTP错误响应已赢得否则会触发.catch()。 (NetworkError或类似的运行时异常触发.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.
})