Глобальный массив, добавленный функцией, обнаруживается как нулевая длина в другом месте - PullRequest
0 голосов
/ 27 января 2011

Я объявил метки массива вверху моего скрипта

var labels = [];

Для добавления в этот массив вызывается функция retrieveLabels:

     function retrieveLabels() {
      labels = [];
      var getLabelsQuery = "SELECT DISTINCT label FROM items ORDER BY label;"
      db.transaction(function(tx) {
           tx.executeSql(getLabelsQuery, [],
                function(tx, labelsResults) {
                     for (var x = 0; x < labelsResults.rows.length; x++) {
                          var labelsRow = labelsResults.rows.item(x);
                          labels.push(labelsRow['label']);
                     }
                     console.log(labels.length);
                     console.log(labels);
                }
           );
      });
 }

Первое консольное сообщение показывает 34 элемента. Второе консольное сообщение показывает ["label1", "label2" ..... "label34"]

Здесь я вызываю функцию здесь:

else {
 init_db();
 retrieveLabels();
 console.log(labels.length);
 console.log(labels);

}

Первое консольное сообщение показывает 0 элементов. Второе консольное сообщение показывает ["label1", "label2" ..... "label34"]

Почему это вдруг стало массивом 0 длины? Или это было изменено внутри retrieveLabels?

Ответы [ 2 ]

1 голос
/ 27 января 2011

Я бы сказал, что tx.executeSql() является асинхронным, и анонимные функции, переданные в качестве аргумента3, фактически выполняются после того, как retrieveLabels(); вернулось.

Итак, во время вашего второго console.log(labels.length); вызван, возможно, запрос не был выполнен.

Вот слегка измененная версия вашей функции, которая принимает обратный вызов в качестве аргумента и вызывает его после заполнения массива labels:

function retrieveLabels(callback) {
    var labels = [];
    var getLabelsQuery = "SELECT DISTINCT label FROM items ORDER BY label;"
    db.transaction(function(tx) {
        tx.executeSql(getLabelsQuery, [],
            function(tx, labelsResults) {
                for (var x = 0; x < labelsResults.rows.length; x++) {
                    var labelsRow = labelsResults.rows.item(x);
                    labels.push(labelsRow['label']);
                }               

                callback(labels);
            }           
        );      
    }); 
}

Затем вы можете вызвать функцию следующим образом:

init_db();
retrieveLabels(function(label) {
    console.log(labels.length);
    console.log(labels);
});
0 голосов
/ 27 января 2011

Ваши вызовы db.transaction или tx.executeSql могут быть асинхронными. Это означает, что метки массива еще не были заполнены, когда вы вызываете console.log (label.length); console.log (этикетки); в другом выражении.

Вы можете проверить, отредактировав код:

db.transaction(function(tx) {
       tx.executeSql(getLabelsQuery, [],
            function(tx, labelsResults) {
                 for (var x = 0; x < labelsResults.rows.length; x++) {
                      var labelsRow = labelsResults.rows.item(x);
                      labels.push(labelsRow['label']);
                 }
                 console.log("tx.exectureSQL done");
            }
       );
  });

и

else {
    init_db();
    retrieveLabels();
    console.log("else done");
}

Таким образом, вы можете увидеть, что на самом деле происходит в первую очередь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...