React Native如何将异步循环获取的值存入useState状态
核心解决思路
将所有异步读取操作的Promise实例收集到数组中,通过Promise.all批量等待所有异步操作完成,再一次性更新状态,完全不需要额外监听临时数组变化。
修正后可直接运行的代码
import { useEffect, useState } from 'react'; import AsyncStorage from '@react-native-async-storage/async-storage'; const [peripherals, setPeripherals] = useState([]); useEffect(() => { const getAllSavedPeripherals = async () => { try { // 读取所有存储的key const allKeys = await AsyncStorage.getAllKeys(); // 过滤出前缀为ble的蓝牙外设key const bleKeys = allKeys.filter(key => key.startsWith('ble')); if (bleKeys.length === 0) { setPeripherals([]); return; } // 生成所有异步读取任务的Promise数组 const readTasks = bleKeys.map(async key => { try { const value = await AsyncStorage.getItem(key); return JSON.parse(value); } catch (err) { console.log('GM: 单个外设数据读取失败: ', err); return null; } }); // 等待所有异步读取任务执行完成 const allResults = await Promise.all(readTasks); // 过滤掉读取失败的空值,一次性更新状态 setPeripherals(allResults.filter(Boolean)); } catch (err) { console.log('GM: 存储key读取失败 : ', err); setPeripherals([]); } } getAllSavedPeripherals(); }, []);
原代码问题说明
forEach循环不支持阻塞等待异步函数执行完成,循环内调用getPeripheral相当于并发发射了多个异步请求,没有时机判断所有请求是否全部执行结束。- 组件作用域声明的
plist临时变量会在组件每次重渲染时被重置,且异步回调捕获的闭包变量可能出现取值异常,无需声明外部临时变量,所有数据处理逻辑可在async函数内部闭环完成。
常见场景扩展
如果需要按顺序串行读取数据而非并发读取,可替换为for...of循环配合await实现,代码如下:
const resultList = []; for (const key of bleKeys) { try { const value = await AsyncStorage.getItem(key); resultList.push(JSON.parse(value)); } catch (err) { console.log('GM: 单个外设数据读取失败: ', err); } } setPeripherals(resultList);
疑问解答
不需要额外编写useEffect监听临时数组变化,Promise.all会在所有异步任务全部完成后才返回结果,此时调用一次setPeripherals即可,不会出现重复更新状态的问题。
内容的提问来源于stack exchange,提问作者gfmoore
相关产品推荐
相关产品推荐

