обогатите массив данными из текстовых файлов

#javascript #arrays

#javascript #массивы

Вопрос:

я пытаюсь обогатить массив данными, которые я загружаю из текстового файла. При первом запросе я получаю данные, содержащие URL-адрес текстового файла. Теперь из этого текстового файла я хотел бы взять первую строку и добавить ее в новый массив. Это работает. Однако я также хотел бы добавить данные из исходного запроса. Кажется, я не могу объединить оба вместе. Это то, что я получил в коде до сих пор:

         var NewArray = [];

        $http({
            method: 'Get',
            url: "https://xxx.azurewebsites.net/api/files/"
        })
            .success(function (data) {

                for (var i = 0; i < data.length; i  ) {

                    var x = data[i].Url;

                    $.when(GetFile(x))
                        .done(function (a1) {

                            var allLines = a1.split("n");
                            var lineOne = allLines[0];
                            
                            NewArray.push({
                                Name: data[i].Name,
                                Url: data[i].Url,
                                text: lineOne,
                            })
                        });
                };

                function GetFile(x) {
                    return $.ajax({
                        method: 'Get',
                        url: x,
                        success: function (data) {

                            //console.log(data);

                        }
                    });
                }

                console.log(NewArray);

            }); 
 

ошибка, которую я получаю, — TypeError: не удается прочитать свойство ‘Name’ неопределенного. Он не может найти данные [i] .Имя и данные[i].Url-адрес, когда я нажимаю на новый массив и в конце появляется «undefined», как я могу это решить?

Ответ №1:

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

Ваш for ... цикл выполняется синхронно и очень быстро, и он завершит перебор всех ваших элементов данных задолго до того, как какая-либо из асинхронных функций в вашем коде действительно запустится. Переменная i будет быстро увеличиваться и попадать data.length , поэтому к тому времени, когда ваша асинхронная функция попытается ввести новое значение, используя data[i] , это попытка доступа data[data.length] , которая, конечно, не определена.

Есть несколько способов исправить это, но я рекомендую заменить for ... цикл на forEach . Это не только согласуется с асинхронным характером остальной части вашего кода, но также удобно предоставляет элемент, к которому вы хотите получить доступ, без риска изменения базовых переменных.

Поскольку замыкания могут быть сложной концепцией, вам может понравиться это сообщение в блоге, в котором предпринята попытка объяснить их в простых терминах.