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

React Native中如何将网络图片转Blob存入SQLite数据库?

解决方案:React Native 网络图片转Base64并存入SQLite数据库

一、修复图片转换函数的返回值问题

你的convertImageToBase64函数没有正确返回转换结果,因为FileReader的onload是异步回调,原代码未将其包装为Promise,导致async函数无返回值。修改后的函数如下:

export const convertImageToBase64 = async (imgUrl) => {
  const response = await fetch(imgUrl);
  const blob = await response.blob();
  
  return new Promise((resolve) => {
    const fr = new FileReader();
    fr.readAsDataURL(blob);
    fr.onload = () => {
      resolve(fr.result); // 正确返回Base64字符串
    };
  });
};

修改说明:

  • 用await替代then嵌套,简化异步逻辑
  • 将FileReader的异步操作包装为Promise,确保函数能返回转换后的结果

二、解决SQLite事务中的异步插入问题

插入时图片字段为空的核心原因:tx.executeSql是异步API但不返回Promise,map里的async函数会让循环提前结束,事务可能在所有图片转换和插入完成前就提交了。需要把每个操作包装为Promise并等待全部完成:

// 表创建建议只在初始化时执行一次
db.transaction((tx) => {
  tx.executeSql(
    "CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, img BLOB, done INTEGER)"
  );
});

// 封装异步插入逻辑
const insertItems = async (result) => {
  await new Promise((resolve, reject) => {
    db.transaction(async (tx) => {
      // 用for...of替代map,确保逐个等待异步操作完成
      for (const item of result) {
        try {
          const base64Img = await convertImageToBase64(imgUrl);
          // 把tx.executeSql包装为Promise,等待SQL执行完成
          await new Promise((sqlResolve) => {
            tx.executeSql(
              "INSERT INTO items (name, img, done) VALUES (?,?,?)",
              [item.name, base64Img, item.done],
              (tx, results) => {
                console.log('插入成功,影响行数:', results.rowsAffected);
                sqlResolve();
              },
              (tx, error) => {
                console.error('插入失败:', error);
                sqlResolve(); // 可根据需求选择是否终止流程
              }
            );
          });
        } catch (err) {
          console.error('图片转换失败:', err);
        }
      }
      resolve();
    }, (error) => {
      reject(error);
      console.error('事务执行失败:', error);
    });
  });
};

// 调用插入函数
insertItems(result);

修改说明:

  1. 用for...of替代map:map会生成未等待的Promise数组,for...of配合await能确保每个插入操作完成后再进行下一个
  2. 包装tx.executeSql为Promise:适配异步等待逻辑,避免SQL操作未完成就进入下一轮循环
  3. 事务整体包装为Promise:确保所有插入操作完成后再结束事务,避免数据不完整

三、额外注意事项

  • 存储格式选择:SQLite的BLOB字段可直接存储Base64字符串,若想节省空间,也可修改转换函数返回原始Blob数据存入
  • 性能优化:图片数量较多时建议分批插入,避免一次性处理大量请求导致应用卡顿
  • 错误处理:完善的异常捕获可避免单个图片处理失败导致整个插入流程中断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 09:35:32