异步 atom

在之前的章节中其实已经出现过了使用异步作为 atom 初始化 read 方法的 atom 示例。这是因为 Jotai 中所有 atom 的创建方法都原生支持使用异步函数作为 atom 的 read 函数和 write 函数。所以异步 atom 的定义与普通 atom 没有什么两样,这里就不再赘述了。

本节所要集中讲述的内容是与异步 atom 相关的一些内容。

异步 atom 的同步使用

jotai/utils里提供了一个loadable函数,可以将一个异步 atom 转换为同步 atom 来使用。loadable的使用非常简单,它就相当于创建 atom 的atom函数,直接套在异步 atom 外面即可。

以下示例展示了loadable的使用方法。

const fetchAtom = atom(async (get) => { ... }); const loadableAtom = loadable(fetchAtom); const Component = () => { const [value] = useAtom(loadableAtom); if (value.state === 'loading') { return <div>Loading...</div>; } if (value.state === 'hasError') { return <div>Error: {value.error}</div>; } if (value.state == 'hasData') { return <div>{value.data}</div> } }

使用loadable创建的 atom 在使用useAtom获取其内容的时候,返回的是以下类型的内容:

type LoadableAtomValue = { state: "loading" | "hasData" | "hasError"; data?: any; error?: any; };

结合这个类型,就可以知道上面示例中各个判断的含义了。

更加低阶的向同步 atom 转换

Jotai 在转换异步 atom 方面,除了提供了loadable函数以外,还提供了一个unwrap函数。与loadable不一样,unwrap不会自动处理异步过程中出现的错误,而是会将其抛出或者使用fallback函数返回的值代替。unwrap函数的使用与loadable函数基本一致,在使用中只需要参考以下unwrap函数的签名提供相应的参数即可。

// 不提供fallback的版本 function unwrap<Value, Args extends unknown[], Result>( atom: Writable<Value, Args, Result> ): WritableAtom<Awaited<Value> | undefined, Args, Result>; // 提供fallback的用于派生atom的版本 function unwrap<Value, Args extends unknown[], Result>( atom: WritableAtom<Value, Args, Result>, fallback: (prev?: Awaited<Value>) => PendingValue ): WritableAtom<Awaited<Value> | PendingValue, Args, Result>; // 提供fallback的用于原始atom的版本 function unwrap<Value, PendingValue>( atom: Atom<Value>, fallback: (prev?: Aawaited<Value>) => PendingValue ): Atom<Awaited<Value> | PendingValue>;

在以上函数签名中,Awaited<Value>都代表一个异步 atom 的执行结果。