Массив пуст вне функции, пытаясь извлечь данные из базы данных, в Javascript

#javascript #arrays

#javascript #массивы

Вопрос:

Я пытаюсь создать приложение с использованием Ionic Framework и Javascript, и я хочу получить все данные из таблицы в массиве, но когда я пытаюсь получить доступ к этому массиву вне функции, он пуст. Я прочитал кое-что, что, возможно, массив заполняется после console.log("length " $scope.cards.length); , но я не знаю, как это решить, чтобы я мог использовать массив после этого.

Это функция для извлечения данных из таблицы (она работает):

  fetchCards: function(success) {
  database.transaction(function(tx) {
    tx.executeSql("SELECT cardId, name, chosen, filePath, found FROM Cards", [], 
      function (tx, results) {
        console.log('success select '   results);
        cards = [];
        for (i = 0; i < results.rows.length; i  ) {
          cards.push(results.rows.item(i));
        }
        success(cards);
      }, 
      function () {
        console.log('error select');
      });
  });
}
  

Здесь я пытаюсь получить доступ к массиву в контроллере:

     .controller('kindergartenController', function($scope, $ionicSideMenuDelegate,service) {

     //list with the difficulties
     $scope.difficultyList=[
     {text:"Easy", value:"easy"},
     {text:"Medium", value:"medium"},
     {text:"Hard", value:"hard"}];

     $scope.data={difficulty:''};

    //redirecting if it presses 
    $scope.goToAnimalsGame = function() {


    if($scope.data.difficulty=='easy'){
      window.location = "#/menu/animalseasy";

      //in this array I want the results
      $scope.cards=[];

      game = new Game(1,"easyAnimalGame");
      console.log("created a new game "   game.getName());
      game.createMemoryGame();

      console.log("difficulty "   $scope.data.difficulty);
      randomNumbers=game.randomNumbers($scope.data.difficulty);
      console.log('Random numbers are:');
      for(i=0;i<randomNumbers.length;i  ){
        console.log(randomNumbers[i]);
      }

      //here is where I call the other function, to get data from database
      service.fetchCards(function(cards) {
        $scope.cards = cards;
      //it shows the good length
        console.log("length "  $scope.cards.length);
      });
      //it shows it's empty
      console.log("length "  $scope.cards.length);
}
  

Любые предложения полезны, спасибо.

Ответ №1:

Он будет отображаться пустым, потому что:

service.fetchCards

является асинхронным, поэтому внутри той функции, в которой вы определяете свой анонимный обратный вызов, не будет срабатывать, пока данные не будут получены.

console.log("length ".... внешняя часть функции будет выполнена сразу после вызова функции fetchCards , но, возможно, до обратного вызова, при котором массив заполняется.

К сожалению, вы можете иметь дело только с заполненным массивом в обратном вызове или из функции, запущенной в обратном вызове.

Вот график выполнения, чтобы помочь:

service.fetchCards();

->

console.log("length "....) ниже приведенной выше функции

->

anonymous callback (function (cards){}) внутри service.fetchCards()

Если это имеет смысл.

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

Решение:

 service.fecthCards(function (data) {
    // do your code
    $scope.cards = cards;
    //it shows the good length
    console.log("length "  $scope.cards.length);

    // manipulate the array within this function or get it to call another function like so
    nowContinue();
});

function nowContinue() {
    // continue what ever it was that you wanted to do using the newly populated information
}
  

Поскольку nowContinue вызывается с помощью анонимного обратного вызова, он будет срабатывать всякий раз, когда запускается обратный вызов, и будет выполняться после того, как вы заполнили локальные переменные контроллера данными.