You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

异步函数嵌套调用的最佳方式及React Native认证Token存储实践

嘿,针对你的两个问题,我来分享下实际开发里常用的最佳实践:

1. 异步函数内部调用另一个异步函数的最佳方式

最推荐的是用 async/await 语法,它能让异步代码看起来和同步代码一样清晰,比嵌套的.then()链可读性高太多,错误处理也更集中。

举个实际例子:

// 先定义一个要被调用的异步函数
async function fetchUserInfo(userId) {
  const response = await fetch(`https://api.example.com/users/${userId}`);
  if (!response.ok) throw new Error('获取用户信息失败');
  return response.json();
}

// 主异步函数里调用它
async function processUser(userId) {
  try {
    // 用await等待异步函数执行完成,拿到结果
    const userInfo = await fetchUserInfo(userId);
    
    // 如果还要调用其他异步函数,直接继续用await就行
    const userPosts = await fetchUserPosts(userInfo.id);
    
    return { ...userInfo, posts: userPosts };
  } catch (error) {
    // 所有异步操作的错误都会被catch到,统一处理
    console.error('处理用户数据出错:', error);
    // 可以把错误抛出去让上层处理,或者返回默认值
    throw error;
  }
}

如果是多个异步函数需要并行执行(互相不依赖),用Promise.all()效率更高:

async function fetchMultipleData() {
  try {
    // 同时发起多个请求,等待所有请求完成
    const [userInfo, systemConfig] = await Promise.all([
      fetchUserInfo(123),
      fetchSystemConfig()
    ]);
    
    // 处理两个请求的结果
    console.log('用户信息:', userInfo);
    console.log('系统配置:', systemConfig);
  } catch (error) {
    // 只要有一个请求失败,就会进入catch
    console.error('请求失败:', error);
  }
}
2. React Native中用AsyncStorage存储Token的最佳实践

你的登录逻辑可以优化成更健壮的版本,结合async/await和错误处理,同时遵循这些实践:

优化后的完整代码

import AsyncStorage from '@react-native-async-storage/async-storage';

// 统一管理存储键,避免拼写错误,后期维护更方便
const STORAGE_KEYS = {
  AUTH_TOKEN: '@app_auth_token'
};

async function login(username, password) {
  const requestOptions = { 
    method: 'POST', 
    headers: { 'Content-Type': 'application/json' }, 
    body: JSON.stringify({ username, password }) 
  };

  try {
    const response = await fetch(`${BASE_URL}/authenticate`, requestOptions);
    
    // 关键:先检查响应状态,fetch不会因为4xx/5xx状态码自动reject
    if (!response.ok) {
      // 尝试解析错误信息,解析失败就用默认提示
      const errorDetails = await response.json().catch(() => ({ message: '登录失败,请检查账号密码' }));
      throw new Error(errorDetails.message);
    }

    const authResult = await response.json();
    const token = authResult.token; // 假设接口返回的token字段是这个

    // 用await确保Token完全存储成功后再返回结果
    await AsyncStorage.setItem(STORAGE_KEYS.AUTH_TOKEN, token);

    // 返回认证结果,方便上层组件处理(比如跳转首页)
    return authResult;
  } catch (error) {
    console.error('登录流程出错:', error);
    // 抛出错误让调用者(比如UI组件)捕获,显示错误提示
    throw error;
  }
}

额外的最佳实践要点

  • 配套封装Token的读取和清除函数:

    // 读取Token
    async function getAuthToken() {
      try {
        return await AsyncStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
      } catch (error) {
        console.error('读取Token失败:', error);
        return null;
      }
    }
    
    // 登出时清除Token
    async function logout() {
      try {
        await AsyncStorage.removeItem(STORAGE_KEYS.AUTH_TOKEN);
        // 这里可以加上跳转登录页等逻辑
      } catch (error) {
        console.error('清除Token失败:', error);
      }
    }
    
  • 考虑Token过期处理:如果接口返回过期时间,可以一起存储,下次读取时检查是否过期:

    async function storeTokenWithExpiry(token, expiresInSeconds) {
      const expiryTimestamp = Date.now() + expiresInSeconds * 1000;
      await AsyncStorage.setItem(STORAGE_KEYS.AUTH_TOKEN, JSON.stringify({ token, expiryTimestamp }));
    }
    
    async function getValidToken() {
      const storedData = await AsyncStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
      if (!storedData) return null;
    
      const { token, expiryTimestamp } = JSON.parse(storedData);
      // 检查是否过期
      if (Date.now() > expiryTimestamp) {
        await logout(); // 过期自动登出
        return null;
      }
      return token;
    }
    
  • 注意AsyncStorage的局限性:它不是加密存储的,Android上存在SharedPreferences,iOS上是NSUserDefaults,如果是高敏感的Token,建议用react-native-keychain这类专门的安全存储库;如果是简易认证场景,AsyncStorage足够用,但要告知用户风险。

内容的提问来源于stack exchange,提问作者newbee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:42:58