我有两个数据集,一个在indexedDB中,一个在PouchDB中(是的,我知道PouchDB是indexedDB的一个实现)。
indexedDB中的一个是房间列表,通过上一页存储在indexedDB中,并显示在当前页面上。
PouchDB中的一个是房间审核员记录的房间使用情况日志。我想迭代第一个列表,并检查每个项目是否出现在审计房间列表中。如果确实出现了,我想设置一个标志来表示。
这是我的Javascript。 (我在浏览器中运行它并且它确实在进程中的某个时刻返回true,因为控制台日志输出显示了这一点,但是该标志没有针对列表项设置。)
我想知道它是否会继续循环审核记录并覆盖" true"值?
这是查询indexedDB并调用查询PouchDB的函数的函数:
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"});
var index = itemStore.createIndex("rooms", ["route_number"]);
};
openRequest.onerror = function(event) {
console.error(event);
};
openRequest.onsuccess = function (event) {
var db = openRequest.result;
db.onerror = function(event) {
// Generic error handler for all errors targeted at this database's requests
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");
var index = itemStore.index("rooms", ["route_number"]);
console.log('DB opened');
var intRouteNumber = parseInt(routeNumber);
//var range = IDBKeyRange.only(intRouteNumber);
itemStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if(cursor) {
var audited;
if(cursor.value.route_number == routeNumber) {
if (checkIfAudited(cursor.value.room_seq)) {
var audited = ' <span class="checked"><i class="fa fa-check"></i></span>';
} else {
var audited = "";
}
$('#mylist').append("<li id="+ cursor.value.room_id +" rel="+ cursor.value.room_seq +"> " + '<small>'+ cursor.value.room_seq + '. </small><a href="/static?action=edit&room_id='+ cursor.value.room_id +'&route_number='+ cursor.value.route_number +'&sequence='+ cursor.value.room_seq +'&roomname='+ cursor.value.room_name +'&capacity='+ cursor.value.room_capacity +'">' + cursor.value.room_name + '</a>'+audited+'</li> ');
}
cursor.continue();
} else {
console.log('Entries all displayed.');
if(!($.jStorage.get('reverseroute', ''))) {
reverseroute = 'asc';
} else {
reverseroute = $.jStorage.get('reverseroute', '');
}
appendHref(reverseroute);
}
};
// Close the db when the transaction is done
transaction.oncomplete = function() {
db.close();
};
};
}
这是查询PouchDB以查看它是否已被审核的函数:
function checkIfAudited(roomseq) {
var today = new Date();
if(is_BST(today) == true) {
var currentHour = today.getHours()+1;
} else {
var currentHour = today.getHours();
}
var currentDay = today.getDate();
var currentMonth = today.getMonth();
options = {},
that = this,
pdb = new PouchDB('pouchroomusage');
options.include_docs = true;
var pouchOpts = {
skipSetup: true
};
var opts = {live: true};
pdb.allDocs(options, function (error, response) {
response.rows.some(function(row){
var auditTime = new Date(row.doc.timestamp);
var auditHour = auditTime.getUTCHours();
var auditDay = auditTime.getDate();
var auditMonth = auditTime.getMonth();
if(row.doc.sequence == roomseq && currentHour == auditHour && currentDay == auditDay && currentMonth == auditMonth) {
var isAudited = true;
console.log('RoomSeq: ' + roomseq + '; auditHour: ' + auditHour + '; currentHour: ' + currentHour + '; auditDay: ' + auditDay);
console.log('currentDay: ' + currentDay + '; auditMonth: ' + auditMonth + '; currentMonth: ' + currentMonth + '; isAudited: ' + isAudited);
} else {
var isAudited = false;
console.log('No matches');
}
return isAudited;
});
});
}
我已经阅读了有关比较两个阵列的其他一些问题和答案。
我不知道如何使用for
循环pdb.allDocs
:(
以下是console.log
的输出:
49没有比赛
RoomSeq:1;审计小时:14;当前小时:14; auditDay:16 currentDay:16; auditMonth:0; currentMonth:0; isAudited:true
2300没有比赛
那么如何在第二个函数到达PouchDB中的匹配记录时停止并返回true?
答案 0 :(得分:1)
在我看来, pouchdb方法alldocs是异步的。
但是你以同步方式测试试听。因此,在返回checkIfAudited
之后,将返回pdb.alldocs回调函数返回的内容。因此,checkIfAudited
始终返回undefined
。
在我看来,您应该只在temStore.openCursor().onsuccess
中创建一次pouchdb实例。然后,您需要在checkIfAudited
函数中正确返回审计状态。
例如,您可以执行以下操作:
itemStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
if (cursor.value.route_number == routeNumber) {
var audited;
options = {},
pdb = new PouchDB('pouchroomusage');
options.include_docs = true;
pdb.allDocs(options, function (error, allDocsResponse) {
if (checkIfAudited(allDocsResponse, cursor.value.room_seq)) audited = ' <span class="checked"><i class="fa fa-check"></i></span>'
else audited = "";
$('#mylist').append("<li id="+ cursor.value.room_id +" rel="+ cursor.value.room_seq +"> " + '<small>'+ cursor.value.room_seq + '. </small><a href="/static?action=edit&room_id='+ cursor.value.room_id +'&route_number='+ cursor.value.route_number +'&sequence='+ cursor.value.room_seq +'&roomname='+ cursor.value.room_name +'&capacity='+ cursor.value.room_capacity +'">' + cursor.value.room_name + '</a>'+audited+'</li> ');
});
};
cursor.continue();
} else {
console.log('Entries all displayed.');
if(!($.jStorage.get('reverseroute', ''))) reverseroute = 'asc'
else reverseroute = $.jStorage.get('reverseroute', '');
appendHref(reverseroute);
};
};
对于checkIfAudited:
function checkIfAudited(allDocs, roomseq) {
var today = new Date();
if(is_BST(today) == true) {
var currentHour = today.getHours()+1;
} else {
var currentHour = today.getHours();
}
var currentDay = today.getDate();
var currentMonth = today.getMonth();
for (i=0; i<allDocs.rows.length; i++) {
var row = allDocs.rows[i];
var auditTime = new Date(row.doc.timestamp);
var auditHour = auditTime.getUTCHours();
var auditDay = auditTime.getDate();
var auditMonth = auditTime.getMonth();
if(row.doc.sequence == roomseq && currentHour == auditHour && currentDay == auditDay && currentMonth == auditMonth) {
console.log('RoomSeq: ' + roomseq + '; auditHour: ' + auditHour + '; currentHour: ' + currentHour + '; auditDay: ' + auditDay);
console.log('currentDay: ' + currentDay + '; auditMonth: ' + auditMonth + '; currentMonth: ' + currentMonth + '; isAudited: ' + isAudited);
return true; ///// <---- return that it is audited
} else {
console.log('No matches');
};
});
return false ///// <---- return false if no iteration has matched
}
答案 1 :(得分:1)
首先,我不会过于喜欢利用Array.prototype.some
的短路行为。使用您可以使用的本机功能。 indexedDB提供了一种内置的方法来停止推进游标,或者只从商店中加载有限数量的对象。
其次,当您只对几个对象感兴趣时,您可能希望避免从商店加载所有对象。使用光标走路商店。由于您似乎想要在满足某些条件时停止迭代,因此只需在此时不要调用cursor.continue。
第三,即使决定首先从商店加载所有对象,使用for循环比利用some
要好得多。通过利用我的意思是以不同于预期的方式使用该功能。我敢打赌,如果你恢复使用带有break语句的for循环,代码将更清晰,因此更容易理解为什么循环不会在你预期的时候中断。
第四,我是否会花时间将indexedDB查询的结果附加到中间数据结构(如数组),而不是立即与DOM交互。它将更多地分开,你会发现代码更容易调试。
第五,在与indexedDB混合使用异步调用时应该非常小心。当你将调用交错到其他promises时,indexedDB就会出现问题。
答案 2 :(得分:0)
这是经过多次调整后我最终得到的结果。
现在每<span class="checked"><i class="fa fa-check"></i></span>
次增加<li>
次,但至少会增加<li>
次。
所以我对CSS做了一点点破解,只显示一个span.checked
:
.checked {
color: #fff;
background-color: #006338;
border-radius: 50%;
padding: 2px 3px;
}
/* only display the first instance of checked */
li > span.checked ~ .checked {
display: none;
}
(我还在我的脚本中发现并修复了另一个错误,我没有设置route_number
或room_id
。)
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"});
var index = itemStore.createIndex("rooms", ["route_number"]);
};
openRequest.onerror = function(event) {
console.error(event);
};
openRequest.onsuccess = function (event) {
var db = openRequest.result;
db.onerror = function(event) {
// Generic error handler for all errors targeted at this database's requests
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");
var index = itemStore.index("rooms", ["route_number"]);
console.log('DB opened');
var intRouteNumber = parseInt(routeNumber);
//var range = IDBKeyRange.only(intRouteNumber);
itemStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
var audited = "";
if(cursor) {
if(cursor.value.route_number == routeNumber) {
$('#mylist').append("<li id="+ cursor.value.room_id +" rel="+ cursor.value.room_seq +"> " + '<small>'+ cursor.value.room_seq + '. </small><a href="/static?action=edit&room_id='+ cursor.value.room_id +'&route_number='+ cursor.value.route_number +'&sequence='+ cursor.value.room_seq +'&roomname='+ cursor.value.room_name +'&capacity='+ cursor.value.room_capacity +'">' + cursor.value.room_name + '</a></li> ');
}
cursor.continue();
} else {
console.log('Entries all displayed.');
if(!($.jStorage.get('reverseroute', ''))) {
reverseroute = 'asc';
} else {
reverseroute = $.jStorage.get('reverseroute', '');
}
appendHref(reverseroute);
asyncCallToPouchDb();
}
};
// Close the db when the transaction is done
transaction.oncomplete = function() {
db.close();
};
};
}
function asyncCallToPouchDb() {
$('#mylist li').each(function(){
var audited = "";
var room_id = $(this).attr('id');
var thisLi = $(this);
audited = callPouchDb(room_id, thisLi);
});
}
function callPouchDb(room_id, thisLi) {
options = {},
pdb = new PouchDB('pouchroomusage');
options.include_docs = true;
var audited = "";
//return new Promise(resolve => {
pdb.allDocs(options, function (error, response) {
result = response.rows;
for (i = 0; i < result.length; i++) {
if (checkIfAudited(result[i], room_id)) {
audited = ' <span class="checked"><i class="fa fa-check"></i></span>';
}
thisLi.append(audited);
}
//thisLi.append(audited);
/*end pdb.allDocs*/
}).then(function (result) {
// handle result
console.log(result);
}).catch(function (err) {
console.log(err);
});
// });
}
function checkIfAudited(row, room_id) {
var today = new Date();
if(is_BST(today) == true) {
var currentHour = today.getHours()+1;
} else {
var currentHour = today.getHours();
}
var currentDay = today.getDate();
var currentMonth = today.getMonth();
var currentYear = today.getYear();
var isAudited = false; ///// <---- define isAudited outside of db iteration scope
var auditTime = new Date(row.doc.timestamp);
var auditHour = auditTime.getUTCHours();
var auditDay = auditTime.getDate();
var auditMonth = auditTime.getMonth();
var auditYear = auditTime.getYear();
if(row.doc.room_id == room_id && currentHour == auditHour && currentDay == auditDay && currentMonth == auditMonth && currentYear == auditYear) {
isAudited = true;
// debug
// console.log('RoomSeq: ' + roomseq + '; auditHour: ' + auditHour + '; currentHour: ' + currentHour + '; auditDay: ' + auditDay);
// console.log('currentDay: ' + currentDay + '; auditMonth: ' + auditMonth + '; currentMonth: ' + currentMonth + '; isAudited: ' + isAudited);
} else {
console.log('No matches');
};
return isAudited
}