javascript回调后没有数组中的项目

时间:2022-05-20 19:07:38

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.
  });
}