Promise 多个异步操作的并发请求处理技巧
在前端开发中,经常需要进行多个异步操作,并发请求是其中一种非常常见的情况。Promise 是处理异步操作的一种技术方案,本文将探讨 Promise 处理多个异步操作的并发请求的技巧。
- Promise.all
在处理多个异步操作时,我们希望能够同时发起请求,并在所有请求完成后执行后续逻辑。Promise.all()方法可以帮助我们实现这个目标。Promise.all()接收一个 Promise 数组作为参数,返回一个新的 Promise 实例。这个新的 Promise 实例在所有 Promise 都成功 resolve 后 resolve,或者任何一个 Promise reject 后立即 reject,返回的是所有 Promise 返回值的数组。
示例代码:
const promise1 = Promise.resolve('promise1') const promise2 = () => new Promise(resolve => setTimeout(() => resolve('promise2'), 3000)) const promise3 = Promise.reject('promise3') Promise.all([promise1, promise2(), promise3]).then((result) => { console.log(result) }).catch((error) => { console.log(error) }) // 控制台输出:promise1 ,[object Promise], promise3
在这个例子中,Promise.all()同时发起了三个异步请求,其中 promise2() 是一个返回Promise的函数。结果输出的是一个包含所有结果的数组,包括 resolve 和 reject 的结果。在处理多个异步请求时,我们需要注意到一个请求的出错可能会影响整体的结果,因此在使用 Promise.all() 时,需要考虑如何处理 reject 状态的 Promise。
- Promise.race
Promise.race() 方法接收一个 Promise 数组作为参数,返回一个新的 Promise 实例,这个实例返回的值是参数中最先 resolve 或 reject 的 Promise 实例的返回值。用这个方法来处理异步请求,是在只需要快速处理某个异步请求的情况下比较有用。
示例代码:
const promise1 = () => new Promise(resolve => setTimeout(() => resolve('promise1'), 3000)) const promise2 = () => new Promise(resolve => setTimeout(() => resolve('promise2'), 2000)) Promise.race([promise1(), promise2()]).then((result) => { console.log(result) }).catch((error) => { console.log(error) }) // 控制台输出:promise2
在这个例子中,promise2() 短时间内能够 resolve,因此整个 Promise.race() 的异步请求快速返回,输出 promise2。
- 控制并发请求数量
在实际前端开发中,我们需要根据接口的阀值来控制并发请求数量。例如在有些情况下,我们不能够发送过多的请求。这个时候,我们可以通过控制每次并发请求数量的方法来实现这个目标。如下面代码中,我们定义了 limitNumDefaut 来控制并发请求数量,对于每一次的异步请求,我们需要将其推入队列中,当队列中的请求量达到 limitNumDefaut 时,需要等待队列里所有请求的返回结果,才可以继续进行下一次的请求。
示例代码:
const limitNumDefaut = 3 const requestQueue = [] let currentRequestNum = 0 function doRequest () { const requestConfig = requestQueue.shift() handleRequest(requestConfig).finally(() => { currentRequestNum-- if (requestQueue.length) { doRequest() } }) } function handleRequest (requestConfig) { currentRequestNum++ return new Promise((resolve, reject) => { axios(requestConfig) .then(response => { resolve(response) }).catch(error => { reject(error) }) }) } function pushRequest (requestConfig) { requestQueue.push(requestConfig) if (currentRequestNum < limitNumDefaut) { doRequest() } } // 使用示例 pushRequest({ method: 'get', url: '/api/user', }) pushRequest({ method: 'get', url: '/api/menu', }) pushRequest({ method: 'get', url: '/api/role', }) pushRequest({ method: 'get', url: '/api/setting', })
在这个例子中,我们定义了一个 requestQueue 数组来存储每个异步请求的配置。我们通过 pushRequest() 方法将每个异步请求加入队列中。当请求队列中的长度小于设定的最大并发数 limitNumDefaut 时,doRequest() 方法会被调用,从队列取出请求去执行。每个请求执行完成后,将 currentRequestNum 减一,如果队列中还有请求,则继续执行 doRequest() 方法。
总结:
以上是 Promise 处理多个异步操作的并发请求的技巧。在使用 Promise.all() 和 Promise.race() 方法时需要注意 reject 的情况。在实际开发中,我们还需要根据接口的阀值控制并发请求数量。通过这些技巧,我们可以更好地处理并发请求,提高 Web 应用的性能,同时也能更好的理解 Promise 的实现原理和使用方法。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6595500beb4cecbf2d97f7af