【问题标题】:refactoring code from syncronous to asyncronous flow将代码从同步流重构为异步流
【发布时间】: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


    【解决方案1】:

    确实,您不需要 new Promise(...) 包装器,因为您已经有了 Promise 驱动的操作。您只是将现有的 Promise 包装在一个新的手动创建的 Promise 中,这不是必需的(并且被认为是反模式)。你可以改成这样:

    const refreshToken = async (): Promise < boolean > => {
        if (refreshPromise.current) {
            return refreshPromise.current;
        }
    
        // getting items from storage asynchronous
        const tokens = await getTokens();
        const refresh = tokens?.refresh;
    
        const refreshData = await tokenRefresh({ variables: { refresh } });
        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 true;
        }
        return false;
    };
    

    注意,我还删除了 await.then() 的混合,因为您通常不想混合这两种编程风格。

    仅供参考,我不知道您的类型语法,所以请原谅这方面的任何轻微语法错误。这仍应向您展示无需将其包装在 new Promise(...) 中即可完成此操作的一般方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-19
      • 1970-01-01
      • 2014-12-05
      • 2018-07-06
      • 2023-03-12
      • 1970-01-01
      • 2014-03-26
      • 2012-02-03
      相关资源
      最近更新 更多