Service Worker 中的同步或顺序获取

Posted

技术标签:

【中文标题】Service Worker 中的同步或顺序获取【英文标题】:Synchronous or Sequential fetch in Service Worker [duplicate] 【发布时间】:2015-12-04 06:40:03 【问题描述】:

我需要从 Service Worker 发送一系列 PUT 和 POST 请求。发送它们的顺序很重要。

要求:

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

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

如何创建一个fetch 请求链,其中每个结果取决于前一个的成功?


我尝试过的:

改为 XHR(假设我可以使用“async: false”,但这在 Service Worker 中是不允许的)。 setTimeout(sendRequest, i*200)。黑客,不可靠。 Promise loops 基于这些示例 ES6 Promise Patterns。这似乎是最有希望的,但这些示例是针对假设成功的简单案例。无法让它与 fetch 一起使用。

上下文:我正在使用 API 请求的“发件箱”来支持离线读取、创建和更新数据。效果很好,除了这个排序问题。

【问题讨论】:

注意:我使用的是原生 ES6 Promises,而“重复”问题是指其他库。 【参考方案1】:

我认为您会想要遵循 ES6 Promise Patterns 页面中的 Sync loop 模式。

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

为了如您所描述的那样工作,您需要在您的 fetch(...).then(...)throw 中明确检查错误 HTTP 响应状态(如果遇到),因为 HTTP 错误响应不会触发.catch()。 (NetworkErrors 或类似的运行时异常触发 .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.
)

【讨论】:

谢谢你,@jeff-posnick。我没有意识到我没有抛出错误,所以这是问题的一部分。不过,我将另一个标记为答案,因为更大的问题是我没有清除队列本身!【参考方案2】:

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

【讨论】:

谢谢@sean-vieira!事实证明,我对 Promise 感到困惑,以至于我无法确保队列本身在处理过程中被清除。 我使用了类似的方法,只是一个递归函数,它获取承诺数组的索引,并在该位置运行一个。您实际上可以在想要运行以下逻辑时创建一些自定义逻辑。

以上是关于Service Worker 中的同步或顺序获取的主要内容,如果未能解决你的问题,请参考以下文章

Service Worker 文件离线事件

[PWA] 9. Service worker registerion && service work's props, methods and listeners

Service worker 简介

Service worker 简介

Service Worker基础知识整理

如何使用 Mock Service Worker 在自定义钩子中模拟获取?