2015-09-08 16 views
4

我需要从服务工作者发送一系列PUT & POST请求。它们发送的顺序很重要。服务工作者同步或顺序提取

要求:

  • 给出的请求方法,URL和JSON的身体,将请求发送
  • 如果成功(response.status < 300):
    • 通行证的身体是成功的功能
    • 呼叫队列中的下一个请求
  • 如果失败:
    • 通行证的responseText或犯错到误差函数
    • 停止执行

如果我简单地通过队列迭代和呼叫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! 事实证明,我很担心我对Promises的困惑,因为我没有确定队列本身在处理过程中被清除。 – AdrianoFerrari

3

我想你会想遵循从ES6 Promise PatternsSync loop模式。

一旦您的“成功”承诺链通过.reduce()设置,您可以附加一个.catch()子句到最后处理错误报告。承诺链内部的任何承诺拒绝/ throw将短路所有.then() s并直接跳到您的.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