Service Worker 中的同步或顺序获取
Synchronous or Sequential fetch in Service Worker
我需要从 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 一起使用。
Context:我正在使用 "outbox" 个 API 请求来支持离线读取、创建和更新数据。效果很好,除了这个订购问题。
与其立即将队列中的每个请求转换为 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);
});
}
我想你会想要关注 Sync loop pattern from that ES6 Promise Patterns 页面。
通过 .reduce()
设置 "success" 承诺链后,您可以在末尾附加一个 .catch()
子句来处理错误报告。承诺链中的任何承诺拒绝/throw
都会使所有 .then()
短路并直接跳到最后的 .catch()
。
为了使其按照您的描述工作,您需要在 fetch(...).then(...)
和 throw
中明确检查错误 HTTP 响应状态(如果您遇到这种情况),因为 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.
})
我需要从 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 一起使用。
Context:我正在使用 "outbox" 个 API 请求来支持离线读取、创建和更新数据。效果很好,除了这个订购问题。
与其立即将队列中的每个请求转换为 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);
});
}
我想你会想要关注 Sync loop pattern from that ES6 Promise Patterns 页面。
通过 .reduce()
设置 "success" 承诺链后,您可以在末尾附加一个 .catch()
子句来处理错误报告。承诺链中的任何承诺拒绝/throw
都会使所有 .then()
短路并直接跳到最后的 .catch()
。
为了使其按照您的描述工作,您需要在 fetch(...).then(...)
和 throw
中明确检查错误 HTTP 响应状态(如果您遇到这种情况),因为 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.
})