JavaScript异步编程
并发执行如果await之间没有相关依赖或顺序关系,可以直接用Promise.all包裹起来并发执行// ⛔ async function loadDashboard() { const user = await fetchUser(); const posts = await fetc...
2025年1月2日
464字
并发执行
- 如果await之间没有相关依赖或顺序关系,可以直接用Promise.all包裹起来并发执行
// ⛔
async function loadDashboard() {
const user = await fetchUser();
const posts = await fetchPosts();
const notifications = await fetchNotifications();
}
// ✅ 并发执行
async function loadDashboard() {
const [user, posts, notifications] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchNotifications()
]);
}以下情况不建议使用并发执行:
- 依赖关系:如果一个请求需要另一个请求返回的数据,就必须顺序执行。
- 竞态条件:如果多个请求会同时修改某个共享资源,可能导致数据不一致。
- 资源限制:并发过多会给服务器或浏览器带来压力。
学会在try块中抛出错误
throw new Error(`HTTP error! status: ${response.status}`);throw new ApiError('Failed to fetch critical data', { cause: error });
轮询请求异步接口
// ⛔ 隐形的内存杀手
async function startPolling() {
setInterval(async () => {
const data = await fetchData();
updateUI(data);
}, 5000);
}存在以下问题:
- 组件或页面卸载后依然在轮询
- 如果 fetchData() 执行得很慢,可能会同时发起多次请求
- 更新 UI 时,目标 DOM 甚至可能已经被移除
class PollingManager {
constructor(options = {}) {
this.controller = new AbortController();
this.interval = options.interval || 5000;
}
async start() {
while (!this.controller.signal.aborted) {
try {
const response = await fetch('/api/data', {
signal: this.controller.signal
});
const data = await response.json();
updateUI(data);
// 等待下一次轮询
await new Promise(resolve => setTimeout(resolve, this.interval));
} catch (error) {
if (error.name === 'AbortError') {
console.log('Polling stopped');
return;
}
console.error('Polling error:', error);
}
}
}
stop() {
this.controller.abort();
}
}
// 在 React 组件中使用
function DataComponent() {
useEffect(() => {
const poller = new PollingManager({ interval: 5000 });
poller.start();
// 组件卸载时停止轮询
return () => poller.stop();
}, []);
return <div>Data: {/* ... */}</div>;
}通过使用 AbortController,可以在需要时终止请求并及时释放资源,更好地控制组件的生命周期和内存占用。

文章评论区
欢迎留言交流