我需要发送一系列PUT&来自服务工作者的POST请求。他们发送的顺序很重要。
要求:
response.status < 300
):
如果我只是遍历队列并为每个请求调用fetch
,网络差异可能(通常会)导致请求无序到达服务器。
如何制作一系列fetch
请求,其中每个结果取决于前一个请求的成功?
我尝试过的事情:
setTimeout(sendRequest, i*200)
。黑客,不可靠。Promise loops
基于这些示例ES6 Promise Patterns。这似乎是最有希望的,但这些例子是假设成功的简单案例。无法使用fetch。上下文:我正在使用&#34;发件箱&#34; API请求支持离线阅读,创建和更新数据。除了这个订购问题外,效果很好。
答案 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.
})