Node.js TS 并发请求
在现代开发中,处理并发请求是提升应用性能的关键。介绍如何使用 TypeScript 和 Node.js 来实现并发请求的解决方案。我们将从多个角度探讨并发请求的实现方式,并提供详细的代码示例。
解决方案
在 Node.js 中,可以通过多种方式来实现并发请求,例如使用 Promise.all
、async/await
结合循环、或者利用第三方库如 axios
和 p-limit
等。这些方法可以有效控制并发数量,避免因过多的并发请求导致系统资源耗尽或被目标服务器限制访问。
接下来,我们将通过具体的代码示例和不同的思路来解决并发请求的问题。
1. 使用 Promise.all 实现并发请求
Promise.all
是最常用的并发请求方式之一。它允许我们同时发起多个请求,并等待所有请求完成后再进行后续操作。
示例代码
typescript
import axios from 'axios';</p>
<p>const urls = [
'https://jsonplaceholder.typicode.com/posts/1',
'https://jsonplaceholder.typicode.com/posts/2',
'https://jsonplaceholder.typicode.com/posts/3'
];</p>
<p>async function fetchAllData() {
try {
const requests = urls.map(url => axios.get(url)); // 创建请求数组
const responses = await Promise.all(requests); // 并发执行所有请求
const data = responses.map(response => response.data); // 提取数据
console.log(data);
} catch (error) {
console.error('Error fetching data:', error);
}
}</p>
<p>fetchAllData();
注意事项
- 如果其中一个请求失败,
Promise.all
会立即抛出错误并终止所有请求。 - 适合用于少量且可靠的请求场景。
2. 使用 p-limit 控制并发数量
当需要处理大量请求时,直接使用 Promise.all
可能会导致资源耗尽或目标服务器拒绝服务。此时可以使用 p-limit
库来限制并发请求数量。
示例代码
typescript import axios from 'axios'; import pLimit from 'p-limit';</p> <p>const urls = Array.from({ length: 10 }, (_, i) => <code>https://jsonplaceholder.typicode.com/posts/${i + 1}
);async function fetchWithLimit() { const limit = pLimit(3); // 设置并发数为 3 const requests = urls.map(url => limit(async () => { try { const response = await axios.get(url); return response.data; } catch (error) { console.error(
Error fetching ${url}:
, error); throw error; } }) );try { const results = await Promise.all(requests); // 等待所有请求完成 console.log(results); } catch (error) { console.error('Some requests failed:', error); } }
fetchWithLimit();
优点
- 通过
p-limit
,可以精确控制并发请求数量,避免对目标服务器造成过大压力。 - 更适合大规模请求场景。
3. 使用 async/await 和 for 循环实现顺序请求
如果希望按顺序执行请求(即一个请求完成后才发起下一个请求),可以使用 async/await
和 for
循环。
示例代码
typescript import axios from 'axios';</p> <p>const urls = [ 'https://jsonplaceholder.typicode.com/posts/1', 'https://jsonplaceholder.typicode.com/posts/2', 'https://jsonplaceholder.typicode.com/posts/3' ];</p> <p>async function fetchSequentially() { const results: any[] = []; for (const url of urls) { try { const response = await axios.get(url); // 按顺序发起请求 results.push(response.data); } catch (error) { console.error(<code>Error fetching ${url}:
, error); } } console.log(results); }fetchSequentially();
注意事项
- 这种方式虽然简单,但效率较低,因为每个请求都需要等待上一个请求完成。
- 适用于对请求顺序有严格要求的场景。
4. 使用 RxJS 实现流式并发控制
对于更复杂的场景,可以使用 RxJS 库来实现流式并发控制。RxJS 提供了强大的工具来管理异步操作和并发行为。
示例代码
typescript import { from } from 'rxjs'; import { mergeMap, take } from 'rxjs/operators'; import axios from 'axios';</p> <p>const urls = Array.from({ length: 10 }, (_, i) => <code>https://jsonplaceholder.typicode.com/posts/${i + 1}
);from(urls) // 将 URL 数组转换为 Observable .pipe( mergeMap(url => axios.get(url).then(res => res.data), 3) // 控制并发数为 3 ) .subscribe({ next: data => console.log(data), error: err => console.error('Error:', err), complete: () => console.log('All requests completed.') });
优点
- RxJS 提供了丰富的操作符,可以灵活地控制并发行为。
- 适合处理复杂的数据流和异步操作。
四种实现 Node.js 和 TypeScript 并发请求的方式:
1. Promise.all:适用于少量可靠请求。
2. p-limit:适用于需要限制并发数量的大规模请求。
3. async/await + for 循环:适用于顺序执行请求的场景。
4. RxJS:适用于复杂的数据流和异步操作。
根据具体需求选择合适的方案,可以显著提升应用的性能和稳定性。