AngularJs - Array.push () внутри $ http.get () создает некорректный массив - PullRequest
0 голосов
/ 24 января 2019

Я не могу понять, что не так с моим кодом. Кажется, это проблема с JavaScript.

Я загружаю локальный текстовый файл, используя $ http.get ( Есть ли другой способ? ). Я хочу поместить этот контент в массив. Для тестирования я просто нажимаю на любую строку, чтобы убедиться, что она не имеет отношения к реальному текстовому файлу.

 var myArray = [];
 $http.get(localFilePath).then(
        function(success){
            myArray.push("123");
        },
        function(error){
            // other stuff
        });

console.log(myArray);

Этот простой код не будет генерировать правильный массив. Вот скриншот из Chrome dev tool, если я console.log созданный массив:

enter image description here

Теперь это похоже на правильный массив, но это не так. Если я console.log(myArray.length), то возвращает 0 .

Вот вместо этого, как должен выглядеть правильный массив с использованием того же кода myArray.push("123") вне $http.get() функции:

enter image description here

Может кто-нибудь сказать, в чем разница между двумя массивами и почему первый создается по-другому, если я делаю это внутри функции $ http.get () ?

Ответы [ 3 ]

0 голосов
/ 24 января 2019

Это асинхронная проблема. Вы вызываете console.log() вне функции "разрешения" обещания.

var myArray = []
$http.get(localFilePath).then(function(result) {
  myArray.push("123")
})

// outside resolve function     
console.log(myArray)

Поскольку это асинхронная операция, эта функция разрешения вызывается только после завершения запроса $http.get() (обычно через несколько сотен миллисекунд). Однако он НЕ ждет, поэтому остальная часть кода продолжает выполняться. Таким образом, он запускает get(), а затем сразу же запускает console.log() до того, как http-запрос сможет завершиться, поэтому он не заполняет массив к моменту вызова console.log().

Если бы вы поместили console.log() внутри функции разрешения, вы бы увидели, что массив заполнен правильно, потому что он ждал завершения http-запроса, заполнил массив, и только затем сделал распечатать результат.

$http.get(localFilePath).then(function(result) {
  myArray.push("123")

  // inside resolve function     
  console.log(myArray)
})
0 голосов
/ 25 января 2019

Я понял вашу проблему и попробовал код ниже, и я получаю тот же массив, это правильно.Вы назначаете push-объект, возвращаемый из сервиса вместо array.Array.push () будет работать так же с сервисом $ http.get () и внешним сервисом $ http.get ()

  var myArray = [];
  $http.get(localFilePath).then(
    function(success){
        myArray.push("123");
       return success
    },
    function(error){
        // other stuff
     return success
    });

  console.log(myArray);
  var myArray2 = [];
  myArray2.push("123");
  console.log(myArray2);
0 голосов
/ 24 января 2019

Поскольку вы ведете console.log, прежде чем массив получит значение, скорее всего, и внутри консоли chrome обновляет массив (поскольку он является ссылкой), но не длину (поскольку он является примитивом). Вот почему как часть массива вы можете видеть, что свойство длины установлено правильно. Если вы делаете:

var myArray = [];
let $http = { get: () => {
    var p = new Promise((resolve, reject) => {
        setTimeout(() => resolve('hi'), 1000);
    })
    return p;
}}
 $http.get('').then(
  function(success){
      myArray.push("123");
      console.log(myArray, myArray.length, 'after');
  },
  function(error){
      // other stuff
  }
);
console.log(myArray, myArray.length, 'before');

Вы можете понять, что я имею в виду.

...