如何在手动读取RTK Query缓存前确保对应接口请求已发送?
你写的写法是完全可行的。
原理说明
api.endpoints.getPost.initiate(postId) 方法返回的 Promise 会在请求完全结束(无论成功失败)后才会 resolve,所以你用 await 等待这个 dispatch 执行完成之后,getPost 的请求状态和返回数据已经同步更新到 Redux store 中了,这时候调用 select 方法读取到的就是最新的请求结果。
如何确认请求完成以及完善边界处理
你调用 api.endpoints.getPost.select(postId)(getState()) 得到的返回值中包含完整的请求状态字段,可以直接通过这些字段判断请求状态,同时补充错误处理避免后续逻辑报错:
isSuccess:布尔值,为 true 代表请求成功完成,data 字段有有效值isError:布尔值,为 true 代表请求失败status:字符串,可选值为pending/fulfilled/rejected,分别对应请求中、请求成功、请求失败error:请求失败时的错误信息
优化后的代码示例
const api = createApi({ baseQuery: fetchBaseQuery(), endpoints: (builder) => ({ getPost: builder.query({ query: (id) => `/posts/${id}`, }), getBook: builder.query({ async queryFn(postId, { dispatch, getState }) { // 等待getPost请求完成(有缓存会直接走缓存,不会重复请求) await dispatch(api.endpoints.getPost.initiate(postId)) // 拿到完整的请求状态和数据 const postQueryState = api.endpoints.getPost.select(postId)(getState()) // 处理请求失败的情况 if (postQueryState.isError) { return { error: postQueryState.error } } const post = postQueryState.data // 后续使用post.xxx参数查询书籍 const bookRes = await myFetch(`/books/${post.xxx}`) return { data: bookRes } }, }), }), })
额外说明
如果对应 postId 的 getPost 请求之前已经发起过,且缓存未过期,调用 initiate 不会触发新的网络请求,会直接复用缓存数据,Promise 会立刻 resolve,不会产生额外的性能开销。
内容的提问来源于stack exchange,提问作者Mxcpanel
相关产品推荐
相关产品推荐

