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

React Native:db.transaction内更新数组后外部无法读取的疑问

React Native SQLite异步操作后数组无法正确访问的解决方案

你遇到的核心问题是SQLite的数据库操作是异步执行的:db.transaction和内部的tx.executeSql不会阻塞后续代码运行,外部读取数组的逻辑会先于数据库查询的回调函数执行,所以此时rcpts还是初始的空数组。下面是具体的解决方法:

方法1:用Promise封装操作,配合async/await

把数据库查询逻辑封装成返回Promise的函数,通过async/await让代码按预期顺序执行:

let rcpts = []
const db = SQLite.openDatabase('digit.db');

// 封装数据库查询为Promise函数
function fetchReceipts() {
  return new Promise((resolve, reject) => {
    db.transaction(tx => {
      tx.executeSql(
        "SELECT id,date, agentNo, custName, custNo, paidAmount, custBalance, payMode, revGroup FROM tblRcpt ORDER BY Id DESC LIMIT 100 ",
        null,
        (tx, result) => {
          const rcptlist = [];
          const len = result.rows.length;
          if (len > 0) {
            for (let i = 0; i < len; i++) {
              const item = result.rows.item(i);
              rcptlist.push({
                rcptNo: item.id,
                rcptdate: item.date,
                agentNo: item.agentNo,
                custName: item.custName,
                custNo: item.custNo,
                paidAmount: item.paidAmount,
                custBalance: item.custBalance,
                payMode: item.payMode,
                revGroup: item.revGroup
              });
              // 注意:删除原代码中多余的i++,否则会跳过一半数据
            }
          }
          resolve(rcptlist);
        },
        (error) => {
          reject(error);
        }
      );
    });
  });
}

// 用async/await调用异步操作
async function pushreceipts() {
  try {
    rcpts = await fetchReceipts();
    Alert.alert("Data Push finished.");
    
    // 现在可以正常访问rcpts数组
    console.log(rcpts.length);
    rcpts.forEach((item, index) => {
      console.log(`第${index+1}条收据:`, item);
    });
    
    // 在这里执行fetch发送数据的逻辑
  } catch (error) {
    Alert.alert(`查询失败:${error.message}`);
  }
}

方法2:把后续操作直接放到回调函数内部

既然回调函数是数据库查询完成后才触发的,所有需要使用rcpts的逻辑都可以直接放在这个回调里:

let rcpts = []
const db = SQLite.openDatabase('digit.db');

function pushreceipts(){  
  let rcptlist =[];
  db.transaction(tx=>{
    tx.executeSql(
      "SELECT id,date, agentNo, custName, custNo, paidAmount, custBalance, payMode, revGroup FROM tblRcpt ORDER BY Id DESC LIMIT 100 ",
      null,
      (tx,result)=>{          
        const len = result.rows.length;
        if (len>0){
          for(let i =0;i<len;i++){
            const item = result.rows.item(i);              
            rcptlist.push({
              rcptNo : item.id,
              rcptdate : item.date,
              agentNo : item.agentNo,
              custName : item.custName,
              custNo : item.custNo,
              paidAmount : item.paidAmount,
              custBalance : item.custBalance,
              payMode : item.payMode,
              revGroup : item.revGroup
            });
            // 删除原代码中多余的i++,避免跳过数据
          } 
        }
        rcpts = rcptlist;
        Alert.alert("Data Push finished.")
        
        // 把需要使用rcpts的逻辑移到这里
        console.log(rcpts.length);
        rcpts.forEach((item, index) => {
          console.log(`rcpts数组长度:${rcpts.length},第${index+1}条数据`, item);
        });
        
        // 在这里执行fetch发送数据的逻辑
        
      },
      (error) =>{
        Alert.alert(`查询错误:${error.message}`);
      }
    );
  });
}

额外注意事项

  • 原代码的for循环中多了一行i++,这会导致每次循环i自增2,直接跳过一半的数据,必须删除。
  • 错误处理时尽量输出error.message,而非直接弹出error对象,更便于排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 08:30:54