依赖查询
useQuery 依赖查询
依赖查询(又称串行查询)需等待前一个查询完成,才能执行。实现这一点非常简单:只需使用 enabled 选项来告知查询它何时可以运行:
JavaScript
1// Get the user2const { data: user } = useQuery({3 queryKey: ['user', email],4 queryFn: () => getUserByEmail(email.value),5})6 7const userId = computed(() => user.value?.id)8const enabled = computed(() => !!user.value?.id)9 10// Then get the user's projects11const {12 status,13 fetchStatus,14 data: projects,15} = useQuery({16 queryKey: ['projects', userId],17 queryFn: () => getProjectsByUser(userId.value),18 enabled, // The query will not execute until `enabled == true`19})projects 查询将起始于:
TypeScript
1status: 'pending'2isPending: true3fetchStatus: 'idle'一旦 user 可用,projects 查询就会被 enabled,并随即进入:
TypeScript
1status: 'pending'2isPending: true3fetchStatus: 'fetching'获取项目后,它将进入:
TypeScript
1status: 'success'2isPending: false3fetchStatus: 'idle'useQueries 依赖查询
动态并行查询 —— useQueries 同样可依赖于先前的查询,实现方式如下:
TypeScript
1// Get the users ids2const { data: userIds } = useQuery({3 queryKey: ['users'],4 queryFn: getUsersData,5 select: (users) => users.map((user) => user.id),6})7 8const queries = computed(() => {9 return userIds.value?.length10 ? userIds.value.map((id) => {11 return {12 queryKey: ['messages', id],13 queryFn: () => getMessagesByUsers(id),14 }15 })16 : []17})18 19// Then get the users messages20const usersMessages = useQueries({21 queries, // if userIds.value is undefined or has no items, an empty array will be returned22})注意:useQueries 返回的是一个查询结果数组。
关于性能的一点说明
按定义,依赖查询构成了一种 请求瀑布,这会损害性能。假设两个查询耗时相同,串行执行它们所需时间总是并行执行的两倍;当这种情况发生在高延迟的客户端上时,性能影响尤为显著。如果可能,最好重构后端 API,使两个查询能够并行拉取;不过在实际中,这并不总是可行。
在上述示例中,与其先拉取 getUserByEmail 以支持后续的 getProjectsByUser,不如引入一个新的 getProjectsByUserEmail 查询,从而压平该请求瀑布。