解决 Promise 并发请求时的超时和取消问题

· 约 6 分钟读完

Promise 是 JavaScript 中一种处理异步操作的机制,它可以让我们更方便地处理异步操作,避免回调地狱等问题。在前端开发中,我们常常需要发起多个并发请求,这时候就需要解决 Promise 并发请求时的超时和取消问题。

什么是超时和取消问题

在并发请求的场景下,我们可能会遇到一些问题。例如,某个请求可能会因为网络问题或者服务器问题而一直没有响应,导致其他请求也无法继续执行。此外,如果我们需要在一定时间内获取所有请求的结果,那么如果某个请求一直没有响应,我们可能需要考虑超时的问题。另外,如果我们需要取消某个请求,也需要解决这个问题。

解决方案

超时问题

超时问题可以通过 Promise.race() 方法解决。Promise.race() 方法接收一个 Promise 数组作为参数,返回一个新的 Promise 对象。当 Promise 数组中的任意一个 Promise 对象状态改变时,返回的 Promise 对象状态也会改变。具体来说,当 Promise 数组中的某个 Promise 对象成功时,返回的 Promise 对象也会成功;当 Promise 数组中的某个 Promise 对象失败时,返回的 Promise 对象也会失败。另外,Promise.race() 方法会返回第一个状态改变的 Promise 对象的结果。

我们可以利用 Promise.race() 方法来实现超时功能。具体来说,我们可以创建一个 Promise 对象,然后使用 Promise.race() 方法将其与一个定时器 Promise 对象组合起来。如果定时器 Promise 对象先状态改变了,那么说明超时了;否则,就说明请求成功或失败了。

上面的代码中,timeoutPromise() 方法接收一个 Promise 对象和一个超时时间,返回一个新的 Promise 对象。在这个方法中,我们使用 Promise.race() 方法将传入的 Promise 对象与一个定时器 Promise 对象组合起来,如果定时器 Promise 对象先状态改变了,就会返回一个超时错误。

取消问题

取消问题可以通过 AbortController 和 AbortSignal 解决。AbortController 是一个控制器,用于控制一个或多个正在进行的操作。AbortSignal 是一个信号,用于通信操作的状态。当 AbortController 调用 abort() 方法时,与该控制器关联的所有操作都会被取消,而与该控制器关联的 AbortSignal 将被激活。

我们可以在发起请求时使用 AbortController 和 AbortSignal 对象,然后在需要取消请求的时候调用 AbortController 的 abort() 方法即可。

上面的代码中,fetchWithAbort() 方法接收一个 URL 和一些配置选项,返回一个新的 Promise 对象。在这个方法中,我们创建了一个 AbortController 对象和一个 AbortSignal 对象,并将 AbortSignal 对象作为请求的 signal 参数。然后,我们将 AbortController 的 abort() 方法赋值给返回的 Promise 对象的 abort 属性,以便在需要取消请求时调用。

示例代码

上面的代码中,我们使用 timeoutPromise() 方法和 fetchWithAbort() 方法来解决超时和取消问题。然后,我们创建了三个并发请求,并使用 Promise.all() 方法等待它们全部完成。最后,我们取消了第二个请求。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d41377a941bf71347b92fe