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

JavaScript函数返回undefined:已定义变量且从IndexedDB取值仍异常

问题根源:IndexedDB是异步操作,你的函数同步返回了

你遇到的问题核心在于IndexedDB的所有操作都是异步的,而你的code1函数是同步执行的——函数在触发IndexedDB的请求后,还没等异步操作完成(也就是onsuccess回调执行),就已经执行完毕,自然返回undefined。

下面给你两种可行的解决方案,适配不同的代码风格:

方案1:用Promise封装(推荐,现代JS写法)

把整个检索逻辑封装成Promise,这样你可以用async/await或者.then()来优雅地获取异步结果:

function code1(sname) {
  return new Promise((resolve, reject) => {
    const request1 = indexedDB.open("footballDatabase", 1);
    
    request1.onsuccess = function(evt) {
      const db = evt.target.result;
      const objectStore = db.transaction("teamsData").objectStore("teamsData");
      const cursorRequest = objectStore.openCursor();
      
      cursorRequest.onsuccess = function(event) {
        const cursor = event.target.result;
        if (cursor) {
          if (cursor.value.name === sname) {
            // 匹配到目标数据,resolve返回结果
            resolve(cursor.value);
            db.close(); // 记得关闭数据库连接
          } else {
            // 没匹配到,继续遍历下一条
            cursor.continue();
          }
        } else {
          // 遍历完所有数据都没找到,resolve返回null
          resolve(null);
          db.close();
        }
      };
      
      cursorRequest.onerror = function(err) {
        reject(err);
        db.close();
      };
    };
    
    request1.onerror = function(err) {
      reject(err);
    };
  });
}

// 调用方式(用async/await):
async function getTargetTeam(sname) {
  try {
    const result = await code1(sname);
    if (result) {
      console.log("找到匹配数据:", result);
      // 这里处理你的业务逻辑
    } else {
      console.log("没有找到对应名称的数据");
    }
  } catch (err) {
    console.error("检索过程出错:", err);
  }
}

// 或者用.then()链式调用:
code1("曼联")
  .then(result => {
    result ? console.log("找到数据:", result) : console.log("无匹配结果");
  })
  .catch(err => console.error(err));

方案2:使用回调函数(传统写法)

如果不想用Promise,也可以给code1添加一个回调参数,在异步操作完成后调用回调返回结果:

function code1(sname, callback) {
  const request1 = indexedDB.open("footballDatabase", 1);
  
  request1.onsuccess = function(evt) {
    const db = evt.target.result;
    const objectStore = db.transaction("teamsData").objectStore("teamsData");
    const cursorRequest = objectStore.openCursor();
    
    cursorRequest.onsuccess = function(event) {
      const cursor = event.target.result;
      if (cursor) {
        if (cursor.value.name === sname) {
          // 匹配到数据,调用回调返回结果
          callback(null, cursor.value);
          db.close();
        } else {
          cursor.continue();
        }
      } else {
        // 遍历完毕无匹配,回调返回null
        callback(null, null);
        db.close();
      }
    };
    
    cursorRequest.onerror = function(err) {
      callback(err, null);
      db.close();
    };
  };
  
  request1.onerror = function(err) {
    callback(err, null);
  };
}

// 调用方式:
code1("切尔西", function(err, result) {
  if (err) {
    console.error("检索出错:", err);
    return;
  }
  result ? console.log("找到数据:", result) : console.log("未找到匹配项");
});

额外性能优化建议

其实你不需要遍历整个游标来查找匹配项,IndexedDB支持索引(Index),如果name字段是常用查询条件,建议给teamsData对象仓库创建一个name索引,这样可以直接通过索引快速定位数据,避免全表扫描:

// 先确保在数据库升级时创建索引(首次打开数据库版本号更新时执行):
// request1.onupgradeneeded = function(evt) {
//   const db = evt.target.result;
//   const objectStore = db.createObjectStore("teamsData", { keyPath: "id" });
//   objectStore.createIndex("name", "name", { unique: false }); // 创建name字段的索引
// };

// 优化后的查询函数:
function code1(sname) {
  return new Promise((resolve, reject) => {
    const request1 = indexedDB.open("footballDatabase", 1);
    
    request1.onsuccess = function(evt) {
      const db = evt.target.result;
      const objectStore = db.transaction("teamsData").objectStore("teamsData");
      const nameIndex = objectStore.index("name");
      const getRequest = nameIndex.get(sname);
      
      getRequest.onsuccess = function() {
        resolve(getRequest.result);
        db.close();
      };
      
      getRequest.onerror = function(err) {
        reject(err);
        db.close();
      };
    };
    
    request1.onerror = function(err) {
      reject(err);
    };
  });
}

这样查询效率会比遍历游标高很多,尤其是数据量较大的时候。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:35:27