You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React Native中SQLite的Async/Await异步处理实现及问题咨询

React Native中SQLite的Async/Await异步处理实现及问题咨询

我明白你现在遇到的问题了——React Native里的SQLite默认是基于回调的API,你直接在tx.executeSql的回调里加async/await没法让整个getDate函数真正按异步流程执行,因为外层的db.transaction并不会等待内部的异步逻辑完成,这就导致你的异步操作相当于“脱缰”了,没法被正确管控。

先说说你原来写法的问题:

  • db.transaction本身是异步的,但它没有返回Promise,所以你的async function getDate会直接执行完毕,不会等待内部的数据库查询完成。
  • 就算你给tx.executeSql的回调加了async,这个回调的异步操作也不会被外层的transaction感知到,后续的逻辑自然没法按你预期的顺序执行。
  • 如果results.rows.item(0).date是同步数据,那这里的await完全是多余的;如果它需要异步处理,那也得把整个查询逻辑包装成Promise才能正确等待。

下面给你两种可行的解决方案,核心思路都是把SQLite的回调式API包装成Promise,这样就能用async/await来优雅地处理异步流程了:

方案一:封装通用的异步SQLite操作函数

先写两个通用的工具函数,把transactionexecuteSql都转换成Promise风格:

// 封装executeSql为Promise
function executeSqlAsync(tx, sql, params = []) {
  return new Promise((resolve, reject) => {
    tx.executeSql(
      sql,
      params,
      (tx, results) => resolve(results),
      (tx, error) => reject(error)
    );
  });
}

// 封装transaction为Promise
function transactionAsync(db, callback) {
  return new Promise((resolve, reject) => {
    db.transaction(
      (tx) => {
        // 执行回调里的异步操作,完成后resolve
        callback(tx).then(resolve).catch(reject);
      },
      (error) => reject(error) // 处理transaction级别的错误
    );
  });
}

然后改造你的getDate函数:

async function getDate() {
  try {
    // 用await等待数据库事务完成
    const results = await transactionAsync(db, async (tx) => {
      // 等待SQL查询完成并返回结果
      return await executeSqlAsync(tx, 'SELECT * FROM dateTime where id=?', [1]);
    });

    const len = results.rows.length;
    if (len > 0) {
      // 如果date需要异步处理(比如调用其他async函数),在这里加await
      // 示例:const a = await someAsyncOperation(results.rows.item(0).date);
      const a = results.rows.item(0).date; // 如果是同步数据就直接赋值
      setDate(a);
    } else {
      console.log('>>>>>tarih yok');
    }
  } catch (error) {
    // 统一捕获数据库操作中的错误
    console.error('获取日期数据失败:', error);
  }
}

方案二:直接在getDate里包装Promise(适合简单场景)

如果你的场景比较简单,不想写通用工具函数,也可以直接把整个查询逻辑包装成Promise:

async function getDate() {
  try {
    const results = await new Promise((resolve, reject) => {
      db.transaction(tx => {
        tx.executeSql(
          'SELECT * FROM dateTime where id=?',
          [1],
          (tx, results) => resolve(results),
          (tx, error) => reject(error)
        );
      }, (error) => reject(error));
    });

    const len = results.rows.length;
    if (len > 0) {
      const a = results.rows.item(0).date;
      // 如果这里有异步操作,比如调用其他async函数
      // const processedDate = await processDateAsync(a);
      // setDate(processedDate);
      setDate(a);
    } else {
      console.log('>>>>>tarih yok');
    }
  } catch (error) {
    console.error('查询出错:', error);
  }
}

这样改造后,整个getDate函数就会正确等待数据库查询完成,再执行后续的setDate逻辑,完全符合async/await的异步流程预期。

备注:内容来源于stack exchange,提问作者Muhammet

火山引擎 最新活动