import { DependencyList, useCallback, useRef, useState } from 'react';
import useMountedState from './useMountedState';
import { FunctionReturningPromise, PromiseType } from './misc/types';
export type AsyncState<T> =
| {
loading: boolean;
error?: undefined;
value?: undefined;
}
| {
loading: true;
error?: Error | undefined;
value?: T;
}
| {
loading: false;
error: Error;
value?: undefined;
}
| {
loading: false;
error?: undefined;
value: T;
};
type StateFromFunctionReturningPromise<T extends FunctionReturningPromise> = AsyncState<
PromiseType<ReturnType<T>>
>;
export type AsyncFnReturn<T extends FunctionReturningPromise = FunctionReturningPromise> = [
StateFromFunctionReturningPromise<T>,
T
];
//定义一个使用异步的hook
//第一个参数需要被异步执行的函数,fn是一个promise
//第二个参数 重新生成需要被异步执行函数的依赖项
//第三个参数 用来初始化异步函数的初始状态
export default function useAsyncFn<T extends FunctionReturningPromise>(
fn: T,
deps: DependencyList = [],
initialState: StateFromFunctionReturningPromise<T> = { loading: false }
): AsyncFnReturn<T> {
//定义一个ref容器,用来保存上一次调用的Id
const lastCallId = useRef(0);
//这个应该是判断组件挂载状态的hook
const isMounted = useMountedState();
//使用传入的值初始化异步函数的状态
const [state, set] = useState<StateFromFunctionReturningPromise<T>>(initialState);
//定义callback,使用useCallback生成一个缓存的函数对象
const callback = useCallback((...args: Parameters<T>): ReturnType<T> => {
//从ref缓存对象中拿出lastclassId,自加并赋值给callId,表示完成一次调用
//应该是防止缓存的函数被重复调用
const callId = ++lastCallId.current;
//判断函数已经被执行
if (!state.loading) {
//函数被执行完了,设置函数的执行状态为没有执行
set((prevState) => ({ ...prevState, loading: true }));
}
//返回 执行异步函数的promise
return fn(...args).then(
//异步函数执行成功,返回函数的执行的成功信息和函数的状态
(value) => {
//如果被挂载了判断callId是不是等于lastCallId,判断是不是本次调用
//是本次调用的设置state的值
//不是本次调用的返会初始值
isMounted() && callId === lastCallId.current && set({ value, loading: false });
return value;
},
//异步函数执行失败,返回异步函数执行的失败信息和函数的状态
(error) => {
isMounted() && callId === lastCallId.current && set({ error, loading: false });
return error;
}
) as ReturnType<T>;
}, deps);
//将函数的执行信息和缓存的执行异步函数的callback函数返回
//执行callback会得到一个执行了异步函数的promise,就是useCallback中返回的promise
return [state, callback as unknown as T];
}
这个库写的真不错,嘿嘿,这只是我简单了理解,有想法了再补充修改