我需要redux-toolkit中的函数来从其他切片中获取所有数据。
我有这样的代码:
export const getAllData = createAsyncThunk(
'fetchRoot/getAllData',
async (_, { dispatch, rejectWithValue }) => {
const promises = [dispatch(getUsers()), dispatch(getSettings()), dispatch(getClients())];
Promise.all(promises)
.then((res: any) => {
// for (const promise of res) {
// console.log('SSS', promise);
// if (promise.meta.rejectedWithValue) {
// return rejectWithValue(promise.payload);
// }
}
})
.catch((err) => {
console.log(err);
});
}
);
我的问题:如果一个切片取函数(例如:getUsers())被拒绝,如何拒绝promise.all?
getUsers()函数和extraReducers:
export const getUsers = createAsyncThunk('users/getUsers', async (_, { rejectWithValue }) => {
try {
const res = await agent.Users.getAll();
return await res.data;
} catch (err) {
return rejectWithValue(err);
}
});
extraReducers: (builder) => {
builder
// GetUsers lifecycle ===================================
.addCase(getUsers.pending, (state) => {
state.apiState.loading = true;
state.apiState.error = null;
})
.addCase(getUsers.fulfilled, (state, { payload }) => {
state.apiState.loading = false;
state.data = payload;
})
.addCase(getUsers.rejected, (state, { payload }) => {
state.apiState.loading = false;
state.apiState.error = payload;
})
你基本上是对的。一旦Promise.all(promises)
被解析,您将拥有一个数组,其中包含您的每个单独的坦克的解析值。
个人的承诺永远会解决,永远不会拒绝。它们将解析为fulfilled
动作或rejected
动作。在某些情况下,使用导致被拒绝的操作抛出错误的unwrap()
属性是有意义的。但是看看.meta
属性也可以。
你可以用isRejected
或isRejectedWithValue
函数来检查你的动作,它们作为类型保护,这样当你访问像action.meta.rejectedWithValue
这样的属性时就不会有任何TypeScript错误。
这里困难的部分是尝试从循环内部执行return rejectWithValue()
。我建议取消包装以抛出错误。
import { createAsyncThunk, unwrapResult } from "@reduxjs/toolkit";
export const getAllData = createAsyncThunk(
"fetchRoot/getAllData",
async (_, { dispatch }) => {
const promises = [dispatch(getUsers()), dispatch(getSettings()), dispatch(getClients())];
const actions = await Promise.all(promises);
return actions.map(unwrapResult);
}
);
请注意,如果您要使用整个捕获的错误对象到rejectWithValue
,则没有理由在getUsers
中使用try
/catch
。让错误被抛出。
export const getUsers = createAsyncThunk('users/getUsers', async () => {
const res = await agent.Users.getAll();
return res.data;
});