所以我的任务是修复一些按钮,以便在单击它们时出现一个加载微调器。问题是我的解决方案并不理想,因为 intellij 抱怨我有 unessesarry waiting 。 我很想获得你们的集体经验,这样我就知道哪个方向是正确的(如果可能的话,一些解释,因为我也在源代码的其他地方找到了它)
在 ImportExport.tsx 中我有以下内容,其中 setIsExportAktionAktive 是我用来显示按钮正在加载的
const handleOnExport = useCallback(
async (fpNumber?: number) => {
setIsExportAktionAktive(true)
const statusCode2Error: Record<string, string> = {
'403': I18n.t(.....blabla),
'423': I18n.t(.....blabla)
}
try {
// this line is the problem intellij complains , if i remove it ,it does not wait for the export to finish and gets setIsExportAktionAktive(false) almost immediately !
await dispatch(export(fpNumber, statusCode2Error, handleImportExportError))
}catch (error){
console.error(error)
} finally {
setIsExportAktionAktive(false)
}
},
[I18n, dispatch, handleImportExportError]
)
在 ImportExportSlice.ts 中我有以下内容
export const export=
(
fpNumber?: number,
errorMsg?: Record<string, string>,
callback?: (status: string, errorMsg: Record<string, string>) => void
): AppThunk =>
async (dispatch) => {
await (fpNummer ? importExportApi.export(fpNumber) : importExportApi.export())
.catch((error) => {
const statusCode: string = error.response.status.toString()
dispatch(setExportErrorStatusCode(statusCode))
callback?.(statusCode, errorMsg)
})
.finally(() => dispatch(importExportProtokollLoad()))
}
AppThunk 是这样定义的
export type AppThunk = ThunkAction<void, RootState, null, Action<string>>
我可以把它放在州里的切片中,但我不认为/不知道那是否更好。 useCallback 中的异步等待也很糟糕。 有没有办法让我真正返回 Promise 以便我可以链接 then ? 我很确定我在使用当前的解决方案进行代码审查时会遇到困难(如果我将其放入状态也很可能) 有什么想法吗?
它确实看起来毫无用处,因为在通话之后没有什么可做的。即使 thunk 本身似乎也不需要声明 async
和
await
任何东西,因为
export
不会返回任何内容,也没有在
await
之后有任何逻辑。它还将
async/await
与 Promise 链混合在一起,这有点像 Javascript 反模式。更新
export
以返回实际的 Promise,而不是隐式返回 Promise,方法是返回 Promise 链或转换为
async
/
await
。
export const export = (
fpNumber?: number,
errorMsg?: Record<string, string>,
callback?: (status: string, errorMsg: Record<string, string>) => void
): AppThunk => (dispatch) => {
return (fpNummer
? importExportApi.export(fpNumber)
: importExportApi.export()
)
.catch((error) => {
const statusCode: string = error.response.status.toString();
dispatch(setExportErrorStatusCode(statusCode));
callback?.(statusCode, errorMsg);
})
.finally(() => dispatch(importExportProtokollLoad()));
};
async
/
await
:
export const export = (
fpNumber?: number,
errorMsg?: Record<string, string>,
callback?: (status: string, errorMsg: Record<string, string>) => void
): AppThunk => async (dispatch) => {
try {
await (fpNummer
? importExportApi.export(fpNumber)
: importExportApi.export()
);
} catch(error) {
const statusCode: string = error.response.status.toString();
dispatch(setExportErrorStatusCode(statusCode));
callback?.(statusCode, errorMsg);
} finally {
dispatch(importExportProtokollLoad());
}
};
export
正确返回了awaited Promise
handleOnExport
回调应该能够
await
它,或者这里 Promise 也可以返回给调用者。
const handleOnExport = useCallback(
(fpNumber?: number) => {
setIsExportAktionAktive(true)
const statusCode2Error: Record<string, string> = {
'403': I18n.t(.....blabla),
'423': I18n.t(.....blabla)
}
try {
return dispatch(export(
fpNumber,
statusCode2Error,
handleImportExportError
));
} catch (error) {
console.error(error);
} finally {
setIsExportAktionAktive(false));
}
},
[I18n, dispatch, handleImportExportError]
);
如果您对使用 Redux-Toolkit
编写 thunk 感到好奇,这就是它的实现和使用方式:
import { createAsyncThunk } from '@reduxjs/toolkit';
export const export = createAsyncThunk(
"export",
async (
{ fpNumber, errorMsg }: {
fpNumber?: number;
errorMsg?: Record<string, string>;
},
{ dispatch, rejectWithValue } // ThunkAPI
) => {
try {
return fpNummer
? importExportApi.export(fpNumber)
: importExportApi.export();
} catch(error) {
const statusCode: string = error.response.status.toString();
return rejectWithValue({ statusCode, errorMsg });
} finally {
dispatch(importExportProtokollLoad();
}
},
);
const handleOnExport = useCallback(
(fpNumber?: number) => {
setIsExportAktionAktive(true)
const statusCode2Error: Record<string, string> = {
'403': I18n.t(.....blabla),
'423': I18n.t(.....blabla)
}
try {
dispatch(export(
fpNumber,
statusCode2Error,
)).unwrap();
} catch (error) {
console.error(error);
handleImportExportError(error.statusCode, error.errorMsg);
} finally {
setIsExportAktionAktive(false));
}
},
[I18n, dispatch, handleImportExportError]
);