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

如何让PouchDB查询函数匹配到记录时停止迭代并返回true?

问题根源:异步操作的返回值处理错误

你的核心问题在于checkIfAudited函数里调用的pdb.allDocs是异步操作,但你试图同步获取它的返回值——这根本行不通,因为函数会在PouchDB查询完成前就执行完毕,返回的是undefined,而不是你期望的true/false。另外,some方法里的isAudited变量作用域也有问题,导致无法正确终止循环并返回结果。

下面是分步修复方案:

1. 重构checkIfAudited为返回Promise的异步函数

把异步查询逻辑包装成Promise,这样我们可以等待查询完成后再获取结果:

function checkIfAudited(roomseq) {
  return new Promise((resolve, reject) => {
    var today = new Date();
    var currentHour = is_BST(today) ? today.getHours() + 1 : today.getHours();
    var currentDay = today.getDate();
    var currentMonth = today.getMonth();

    const pdb = new PouchDB('pouchroomusage');
    const options = { include_docs: true };

    pdb.allDocs(options, function(error, response) {
      if (error) {
        console.error('PouchDB query error:', error);
        reject(false); // 出错时返回false或者根据需求处理
        return;
      }

      // 使用some方法遍历,找到匹配项就立即终止并返回true
      const isAudited = response.rows.some(row => {
        const auditTime = new Date(row.doc.timestamp);
        const auditHour = auditTime.getUTCHours();
        const auditDay = auditTime.getDate();
        const auditMonth = auditTime.getMonth();

        const matches = row.doc.sequence == roomseq && 
                        currentHour == auditHour && 
                        currentDay == auditDay && 
                        currentMonth == auditMonth;
        
        if (matches) {
          console.log('RoomSeq: ' + roomseq + '; auditHour: ' + auditHour + '; currentHour: ' + currentHour + '; auditDay: ' + auditDay);
          console.log('currentDay: ' + currentDay + '; auditMonth: ' + auditMonth + '; currentMonth: ' + currentMonth + '; isAudited: true');
        } else {
          console.log('No matches for roomseq:', roomseq);
        }
        return matches; // 匹配到就返回true,终止some循环
      });

      resolve(isAudited); // 将最终结果返回
    });
  });
}

修改点说明:

  • 用Promise包裹异步查询,成功时resolve结果,失败时reject
  • 简化了currentHour的判断逻辑(三元运算符更简洁)
  • 把isAudited直接作为some的返回值,避免变量作用域问题,匹配到就立即终止循环
  • 增加了错误处理:如果PouchDB查询出错,直接返回false(你可以根据需求调整错误处理逻辑)

2. 修改getRoomsInRoute中的cursor遍历逻辑,支持异步调用

因为checkIfAudited现在是异步函数,我们需要用async/await来等待它的结果,所以要把cursor的回调改成async函数:

function getRoomsInRoute() {
  var routeNumber = $.jStorage.get('currentRoute', '');
  var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB;
  openRequest = window.indexedDB.open("rooms", 1);

  openRequest.onupgradeneeded = function() {
    var db = openRequest.result;
    var itemStore = db.createObjectStore("rooms", {keyPath: "room_id"});
    itemStore.createIndex("rooms", ["route_number"]);
  };

  openRequest.onerror = function(event) {
    console.error(event);
  };

  openRequest.onsuccess = async function (event) { // 这里改成async函数
    var db = openRequest.result;
    db.onerror = function(event) {
      console.error(event.target);
      console.log("Database error: " + event.target.error.name || event.target.error || event.target.errorCode);
    };

    var transaction = db.transaction(['rooms'], "readwrite");
    var itemStore = transaction.objectStore("rooms");
    console.log('DB opened');
    var intRouteNumber = parseInt(routeNumber);

    itemStore.openCursor().onsuccess = async function(event) { // 这里也改成async函数
      var cursor = event.target.result;
      if(cursor) {
        if(cursor.value.route_number == routeNumber) {
          // 等待checkIfAudited的结果
          const isAudited = await checkIfAudited(cursor.value.room_seq);
          const audited = isAudited ? ' <span class="checked"><i class="fa fa-check"></i></span>' : '';
          
          $('#mylist').append(`<li id="${cursor.value.room_id}" rel="${cursor.value.room_seq}"> 
            <small>${cursor.value.room_seq}.&nbsp;</small>
            <a href="/static?action=edit&amp;room_id=${cursor.value.room_id}&amp;route_number=${cursor.value.route_number}&amp;sequence=${cursor.value.room_seq}&amp;roomname=${cursor.value.room_name}&amp;capacity=${cursor.value.room_capacity}">
              ${cursor.value.room_name}
            </a>${audited}
          </li>`);
        }
        cursor.continue();
      } else {
        console.log('Entries all displayed.');
        const reverseroute = $.jStorage.get('reverseroute', '') || 'asc';
        appendHref(reverseroute);
      }
    };

    transaction.oncomplete = function() {
      db.close();
    };
  };
}

修改点说明:

  • 把openRequest.onsuccess和itemStore.openCursor().onsuccess的回调都改成async函数,这样就能用await等待checkIfAudited的结果
  • 用模板字符串替代字符串拼接,代码更易读且不易出错
  • 简化了reverseroute的判断逻辑
  • 等待checkIfAudited返回结果后,再决定是否添加审计标记,避免了之前同步调用导致的错误

额外优化建议

如果房间数量很多,逐个调用checkIfAudited会产生大量PouchDB查询,建议一次性把所有符合条件的审计记录查出来,在内存中做匹配,性能会好很多:

// 先一次性获取今日当前小时内的所有已审计房间序号
async function getTodayAuditedRooms() {
  const today = new Date();
  const currentHour = is_BST(today) ? today.getHours() + 1 : today.getHours();
  const currentDay = today.getDate();
  const currentMonth = today.getMonth();
  
  const pdb = new PouchDB('pouchroomusage');
  const response = await pdb.allDocs({ include_docs: true });
  
  return response.rows
    .map(row => row.doc)
    .filter(doc => {
      const auditTime = new Date(doc.timestamp);
      return doc.sequence && 
             auditTime.getUTCHours() === currentHour &&
             auditTime.getDate() === currentDay &&
             auditTime.getMonth() === currentMonth;
    })
    .map(doc => doc.sequence); // 只保留房间序号,方便后续查找
}

// 然后在getRoomsInRoute中复用这个结果
openRequest.onsuccess = async function (event) {
  // ... 其他代码 ...
  const auditedRoomSeqs = await getTodayAuditedRooms(); // 一次性获取所有已审计序号
  itemStore.openCursor().onsuccess = function(event) {
    var cursor = event.target.result;
    if(cursor) {
      if(cursor.value.route_number == routeNumber) {
        const isAudited = auditedRoomSeqs.includes(cursor.value.room_seq);
        const audited = isAudited ? ' <span class="checked"><i class="fa fa-check"></i></span>' : '';
        // ... 拼接HTML并添加到列表 ...
      }
      cursor.continue();
    }
    // ... 其他代码 ...
  };
};

这种方式只需要一次PouchDB查询,避免了重复请求,适合房间数量较多的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:25:30