【发布时间】:2021-08-05 12:10:09
【问题描述】:
我有什么
我必须使用为 web 构建的代码,并将其调整为 react native。 最大的问题之一是,web storage(localStorage) 同步工作,而 react-native 存储实现异步工作AsyncStorage。因此,现在所有运行/使用网络存储的代码都必须封装在 async/await 中,或者在 react-native 实现中使用 promises。
重构前的代码 - 使用同步存储
// get items from localstorage - synchronous wrapper implementation
export const getTokens = () => ({
auth:
localStorage.getItem(TOKEN_STORAGE_KEY.AUTH) ||
sessionStorage.getItem(TOKEN_STORAGE_KEY.AUTH),
refresh:
localStorage.getItem(TOKEN_STORAGE_KEY.REFRESH) ||
sessionStorage.getItem(TOKEN_STORAGE_KEY.REFRESH)
});
const refreshPromise = useRef<Promise<boolean>>();
const refreshToken = (): Promise<boolean> => {
if (!!refreshPromise.current) {
return refreshPromise.current;
}
return new Promise(resolve => {
// getting items from storage synchronous
const token = getTokens().refresh;
// nested promise x_x
return tokenRefresh({ variables: { token } }).then(refreshData => {
if (!!refreshData.data.tokenRefresh?.token) {
// this is other method that use localstorage inside promises, more problems x_x
setAuthToken(refreshData.data.tokenRefresh.token, persistToken);
return resolve(true);
}
return resolve(false);
});
});
};
问题
问题是我遇到了在 Promise 中使用存储的情况,为了使其适应 react-native,我必须使用异步流。即在 new Promise() constructor 内使用 async/await,这是一种反模式。
上面带来了很多问题,虽然在promise构造函数中使用async/await是有效的,但首先它会降低代码的可读性,其次更难调试和检查错误。另一个问题是 同步 实现也嵌套了 Promise,这使得重构代码更加复杂。
当前代码 - 使用异步存储
// get items from localstorage - asynchronous wrapper implementation
export const getTokens = async () => {
const auth = await SecureStore.getItemAsync(TokenStorageKey.AUTH);
const refresh = await SecureStore.getItemAsync(TokenStorageKey.REFRESH);
return auth && refresh
? {
auth,
refresh,
}
: null;
};
const refreshPromise = useRef<Promise<boolean>>();
const refreshToken = (): Promise<boolean> => {
if (refreshPromise.current) {
return refreshPromise.current;
}
return new Promise(async resolve => {
// getting items from storage asynchronous
const tokens = await getTokens();
const refresh = tokens?.refresh;
// nested promise x_x
return tokenRefresh({variables: {refresh}}).then(async refreshData => {
if (refreshData.data?.tokenRefresh?.token) {
// this is other method that use localstorage inside promises, more problems x_x
await setAuthToken(refreshData.data.tokenRefresh.token);
return resolve(true);
}
return resolve(false);
});
});
};
我想要什么
据此eslint rule:
如果一个 Promise 执行器函数正在使用 await,这通常表明实际上不需要使用新的 Promise 构造函数,或者可以缩小新的 Promise 构造函数的范围。*
我不清楚如何实现 eslint 规则中提到的内容或使此代码更具可扩展性和更易于调试、删除承诺并避免异步进程的嵌套。
【问题讨论】:
标签: javascript reactjs react-native asynchronous promise