Skip to content

流式请求Hook

@pt/hooks/network/useFetchStream 提供了处理流式响应的Hook,特别适用于SSE(Server-Sent Events)等场景。

基本使用

typescript
import { useFetchStream } from '@pt/hooks/network';

const { 
  current, 
  isLoading, 
  error, 
  fetchStream 
} = useFetchStream(fetch, {
  onError: (err) => console.error('Stream error:', err),
  onComplete: () => console.log('Stream completed'),
  retryTimes: 3,
  retryDelay: 1000
});

async function handleStreamRequest() {
  try {
    const stream = fetchStream('/api/stream', 'POST', {
      message: 'Hello'
    });

    for await (const { current, raw } of stream) {
      console.log('Received message:', current);
      console.log('Raw data:', raw);
    }
  } catch (err) {
    console.error('Error:', err);
  }
}

API 参考

Hook参数

typescript
interface FetchStreamOptions {
  onError?: (error: Error) => void;
  onComplete?: () => void;
  retryTimes?: number;
  retryDelay?: number;
}

Hook返回值

名称类型描述
currentRef<StreamResponse<T> | undefined>当前接收到的消息
isLoadingRef<boolean>加载状态
errorRef<Error | undefined>错误信息
fetchStream(url: string, method?: string, data?: any) => AsyncGenerator发起流式请求

高级用法

自定义错误处理

typescript
const { fetchStream } = useFetchStream(fetch, {
  onError: (error) => {
    console.error('Stream error:', error);
    // 可以在这里添加错误通知或重试逻辑
  },
  retryTimes: 5,
  retryDelay: 2000
});

取消请求

typescript
const { fetchStream } = useFetchStream(fetch);

const controller = new AbortController();

try {
  const stream = fetchStream('/api/stream', 'POST', {
    message: 'Hello'
  }, {
    signal: controller.signal
  });

  // 在需要时取消请求
  setTimeout(() => {
    controller.abort();
  }, 5000);

  for await (const { current } of stream) {
    console.log(current);
  }
} catch (err) {
  if (err.name === 'AbortError') {
    console.log('请求被取消');
  }
}

处理特定类型的响应

typescript
interface ChatMessage {
  role: 'user' | 'assistant';
  content: string;
}

const { fetchStream } = useFetchStream<ChatMessage>(fetch);

const stream = fetchStream('/api/chat', 'POST', {
  message: '你好'
});

for await (const { current } of stream) {
  if (current.role === 'assistant') {
    console.log('AI回复:', current.content);
  }
}

注意事项

  1. 确保服务器支持流式响应
  2. 处理网络断开和重连情况
  3. 合理设置重试次数和延迟
  4. 在组件卸载时正确清理资源
  5. 考虑添加超时处理
  6. 处理错误边界情况

Released under the MIT License.