I'am trying to gather some data from my Chrome Extension Web SQL database with following code:
我试图从Chrome Extension Web SQL数据库中收集一些数据,其代码如下:
function getHistory(year, month, day, callback){
getDayIdByYMD(year, month, day, function(dysId){
var sql = "SELECT DISTINCT HT_URL FROM HISTORIES WHERE HT_DYS_ID = ?;";
db.transaction(function(tx){
tx.executeSql(sql, [dysId], function(tx, results){
var array = [];
$.each(results.rows, function(index, element){
var url = element['HT_URL'];
array.push(url);
});
internalGetHistory(array, dysId, callback);
});
});
});
}
function internalGetHistory(array, dysId, callback){
var returnArray = [];
$.each(array, function(index, url){
getSingleHistoryArray(dysId, url, function(hist){
var tmp = { Url : url, History : hist};
returnArray.push(tmp);
});
});
callback(returnArray);
}
function getSingleHistoryArray(dysId, url, callback){
var sql = "SELECT HT_FROM, HT_TIME FROM HISTORIES WHERE HT_DYS_ID = ? AND HT_URL = ?;";
db.transaction(function(tx){
tx.executeSql(sql, [dysId, url], function(tx, results){
var array = [];
$.each(results.rows, function(index, element){
var obj = {
From : element['HT_FROM'],
Time : element['HT_TIME']
};
array.push(obj);
array.push(2);
});
callback(array);
});
});
}
function printHt(){
getHistory(2016,7 - 1,28, function(o){
console.log(o);
})
}
But my problem is that function internalGetHistory
does not return array. It's always empty. First sql query returns not empet array of urls. The next one - getSingleHistoryArray
should return array of time and timespan corresponding to that url. There is no problem with connection to my database or database entries. I think that this question concrens javascript and callback functions. Thanks for your help!
但我的问题是函数internalGetHistory不返回数组。它总是空的。第一个sql查询返回的不是uret的uret数组。下一个 - getSingleHistoryArray应返回与该url对应的时间和时间跨度数组。连接到我的数据库或数据库条目没有问题。我认为这个问题包含了javascript和回调函数。谢谢你的帮助!
2 个解决方案
#1
0
The calls to getSingleHistoryArray are in a function that gets called once on each element of the input array asynchronously. The rest of the calling function keeps executing in the mean time so
对getSingleHistoryArray的调用是在一个函数中,该函数在输入数组的每个元素上异步调用一次。其余的调用函数在同一时间内保持执行
var returnArray = [];
is followed immediately by
紧随其后
callback(returnArray);
and the function exits with the initialised but unpopulated array.
并且函数以初始化但未填充的数组退出。
Change
function internalGetHistory(array, dysId, callback){
var returnArray = [];
$.each(array, function(index, url){
getSingleHistoryArray(dysId, url, function(hist){
var tmp = { Url : url, History : hist};
returnArray.push(tmp);
});
});
callback(returnArray);
}
to
function internalGetHistory(array, dysId, callback){
var returnArray = [];
$.each(array, function(index, url){
getSingleHistoryArray(dysId, url, function(hist){
var tmp = { Url : url, History : hist};
returnArray.push(tmp);
if(returnArray.length == array.length) {
callback(returnArray);
}
});
});
}
#2
0
The problem currently is getSingleHistoryArray() is an async function and the callback for within each $.each is not being executed by the time internalGetHistory returns. Here is a way to do it with promises: Change:
目前的问题是getSingleHistoryArray()是一个异步函数,并且每个$ .each中的回调都没有在internalGetHistory返回时执行。这是一种通过承诺来实现的方法:变化:
function getSingleHistoryArray(dysId, url, callback){
var sql = "SELECT HT_FROM, HT_TIME FROM HISTORIES WHERE HT_DYS_ID = ? AND HT_URL = ?;";
db.transaction(function(tx){
tx.executeSql(sql, [dysId, url], function(tx, results){
var array = [];
$.each(results.rows, function(index, element){
var obj = {
From : element['HT_FROM'],
Time : element['HT_TIME']
};
array.push(obj);
array.push(2);
});
callback(array);
});
});
}
to:
function getSingleHistoryArray(dysId, url){
var sql = "SELECT HT_FROM, HT_TIME FROM HISTORIES WHERE HT_DYS_ID = ? AND HT_URL = ?;";
db.transaction(function(tx){
tx.executeSql(sql, [dysId, url], function(tx, results){
var array = [];
$.each(results.rows, function(index, element){
var obj = {
From : element['HT_FROM'],
Time : element['HT_TIME']
};
array.push(obj);
array.push(2);
});
return new Promise((res, rej) => res(array));
});
});
}
and change:
function internalGetHistory(array, dysId, callback){
var returnArray = [];
$.each(array, function(index, url){
getSingleHistoryArray(dysId, url, function(hist){
var tmp = { Url : url, History : hist};
returnArray.push(tmp);
});
});
callback(returnArray);
}
to:
function internalGetHistory(array, dysId, callback){
var returnArray = [];
var promises = [];
$.each(array, function(index, url){
promises.push(getSingleHistoryArray(dysId, url));
});
Promises.all(promises).then((arr) => {
// do something with returned array.
});
}
#1
0
The calls to getSingleHistoryArray are in a function that gets called once on each element of the input array asynchronously. The rest of the calling function keeps executing in the mean time so
对getSingleHistoryArray的调用是在一个函数中,该函数在输入数组的每个元素上异步调用一次。其余的调用函数在同一时间内保持执行
var returnArray = [];
is followed immediately by
紧随其后
callback(returnArray);
and the function exits with the initialised but unpopulated array.
并且函数以初始化但未填充的数组退出。
Change
function internalGetHistory(array, dysId, callback){
var returnArray = [];
$.each(array, function(index, url){
getSingleHistoryArray(dysId, url, function(hist){
var tmp = { Url : url, History : hist};
returnArray.push(tmp);
});
});
callback(returnArray);
}
to
function internalGetHistory(array, dysId, callback){
var returnArray = [];
$.each(array, function(index, url){
getSingleHistoryArray(dysId, url, function(hist){
var tmp = { Url : url, History : hist};
returnArray.push(tmp);
if(returnArray.length == array.length) {
callback(returnArray);
}
});
});
}
#2
0
The problem currently is getSingleHistoryArray() is an async function and the callback for within each $.each is not being executed by the time internalGetHistory returns. Here is a way to do it with promises: Change:
目前的问题是getSingleHistoryArray()是一个异步函数,并且每个$ .each中的回调都没有在internalGetHistory返回时执行。这是一种通过承诺来实现的方法:变化:
function getSingleHistoryArray(dysId, url, callback){
var sql = "SELECT HT_FROM, HT_TIME FROM HISTORIES WHERE HT_DYS_ID = ? AND HT_URL = ?;";
db.transaction(function(tx){
tx.executeSql(sql, [dysId, url], function(tx, results){
var array = [];
$.each(results.rows, function(index, element){
var obj = {
From : element['HT_FROM'],
Time : element['HT_TIME']
};
array.push(obj);
array.push(2);
});
callback(array);
});
});
}
to:
function getSingleHistoryArray(dysId, url){
var sql = "SELECT HT_FROM, HT_TIME FROM HISTORIES WHERE HT_DYS_ID = ? AND HT_URL = ?;";
db.transaction(function(tx){
tx.executeSql(sql, [dysId, url], function(tx, results){
var array = [];
$.each(results.rows, function(index, element){
var obj = {
From : element['HT_FROM'],
Time : element['HT_TIME']
};
array.push(obj);
array.push(2);
});
return new Promise((res, rej) => res(array));
});
});
}
and change:
function internalGetHistory(array, dysId, callback){
var returnArray = [];
$.each(array, function(index, url){
getSingleHistoryArray(dysId, url, function(hist){
var tmp = { Url : url, History : hist};
returnArray.push(tmp);
});
});
callback(returnArray);
}
to:
function internalGetHistory(array, dysId, callback){
var returnArray = [];
var promises = [];
$.each(array, function(index, url){
promises.push(getSingleHistoryArray(dysId, url));
});
Promises.all(promises).then((arr) => {
// do something with returned array.
});
}