import { describe, expect, it } from 'vitest' import { useAsync } from './useAsync' /** 手动控制解析时机的 fetcher,复现请求乱序返回 */ function deferredFetcher() { const pending: Array<{ resolve: (v: T) => void; reject: (e: unknown) => void }> = [] const fetcher = () => new Promise((resolve, reject) => { pending.push({ resolve, reject }) }) return { fetcher, pending } } describe('useAsync 并发与乱序', () => { it('后发请求先返回时,先发请求的迟到结果被丢弃', async () => { const { fetcher, pending } = deferredFetcher() const st = useAsync(fetcher, false) const p1 = st.run() const p2 = st.run() pending[1].resolve('新') await p2 pending[0].resolve('旧') await p1 expect(st.data.value).toBe('新') expect(st.loading.value).toBe(false) }) it('迟到的失败不覆盖最新成功结果', async () => { const { fetcher, pending } = deferredFetcher() const st = useAsync(fetcher, false) const p1 = st.run() const p2 = st.run() pending[1].resolve('新') await p2 pending[0].reject(new Error('旧请求失败')) await p1 expect(st.data.value).toBe('新') expect(st.error.value).toBe('') }) it('silent 刷新不置 loading,普通刷新置 loading', async () => { const { fetcher, pending } = deferredFetcher() const st = useAsync(fetcher, false) const p1 = st.run({ silent: true }) expect(st.loading.value).toBe(false) pending[0].resolve(1) await p1 const p2 = st.run() expect(st.loading.value).toBe(true) pending[1].resolve(2) await p2 expect(st.loading.value).toBe(false) expect(st.data.value).toBe(2) }) it('失败时记录 error 并清 loading', async () => { const { fetcher, pending } = deferredFetcher() const st = useAsync(fetcher, false) const p1 = st.run() pending[0].reject(new Error('boom')) await p1 expect(st.error.value).toBe('boom') expect(st.loading.value).toBe(false) expect(st.data.value).toBeNull() }) })