异步客户端组件
useAsync
概览
useAsync 为每次任务执行管理 AbortSignal、状态、结果与错误,并阻止过期结果覆盖较新的状态。
函数签名
ts
type AsyncTask<T> = (signal: AbortSignal) => Promise<T> | T;
function useAsync<T>(
task: AsyncTask<T>,
options?: { immediate?: boolean; onError?: (error: unknown) => void },
): {
status: 'idle' | 'pending' | 'success' | 'error';
data: T | undefined;
error: unknown;
run: () => Promise<T>;
cancel: () => void;
reset: () => void;
};参数
每次执行都会向 task 传入新的 AbortSignal。immediate 默认为 false;设为 true 时,任务会在组件提交后自动执行。onError 用于观察最近一次未取消任务的错误。
返回值
返回任务状态,以及引用稳定的 run、cancel 和 reset。run 返回任务本身的结果,并保留原始拒绝原因。
行为
开始新任务时会中止前一个 AbortController。序号检查会阻止旧结果更新状态。cancel 保留 data 并回到 idle;reset 还会清空 data 和 error。当前任务失败时会将状态设为 error,先调用 onError(如果提供),再保留原始 Promise 拒绝。已取消或已过期的任务不会上报错误。
SSR / RSC
SSR 时状态从 idle 开始;即使启用 immediate,任务也只会在客户端 Effect 中启动。
示例
组合使用
可以先用 useDebounce 稳定输入,再更新任务;关联面板关闭时则可调用 cancel。