JavaScript: Как правильно перебрать массив и использовать значения в качестве ключей? - PullRequest
0 голосов
/ 09 февраля 2019

Я получаю JSON-строку из удаленной конечной точки и хочу использовать значения в качестве ключей.Итак, я перебираю результат, подобный следующему:

(function() {
// Create the connector object
var myConnector = tableau.makeConnector();

var definitions = [];

// Define the schema
myConnector.getSchema = function(schemaCallback) {

$.ajax({
    url: apiUrl,
    type: 'GET',
    crossDomain: true,
    cache: false,
    headers: {
        'X-Auth-Token':'123',
        'X-Auth-User':'user1'
    },
    dataType: "json",
    success: function(response){

        $.each(response,function(key,value){

                console.log("inside loop");
                console.log(value);
                definitions[value.id]
                     = value.name;

        }); 

        console.log("inside ajax");
        console.log(definitions);
    }

});

console.log("done");
console.log(definitions);

// this is where I want to loop through my result
// whithout success (no console output
for (var key in definitions) {
        console.log(key);

    }

}; //     myConnector.getSchema = function(schemaCallback) {

})(); //function() {

Это ответ от API:

[
{
    "id": 123,
    "name": "Name1"
},
{
    "id": 456,
    "name": "Name2"
},
{
    "id": 789,
    "name": "Name3"
}]

Это выходные данные первой команды журнала внутри цикла:

{id: 123, name: "Name1"}
id: 123
name: "Name1"
__proto__: Object

Проблема в том, что последний журнал выглядит следующим образом:

[123: "Name1", 456: "Name3", 789: "Name4"]
123: "Name1"
456: "Name2"
789: "Name3"
length: 0
__proto__: Array(0)

Проблема очевидна: длина массива отображается как ноль.И это я не понимаю.

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

Что я не так делаю?

Дополнительная информация

Я работаю над веб-соединителем для Tableau, который будет подключаться к конечной точке службы RESTful.К сожалению, я не могу опубликовать реальный URL RESTful, потому что он предоставляет личные данные.

Я использую этот симулятор: http://tableau.github.io/webdataconnector/Simulator/

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

Я сейчас попробовал скрипт в Firefox (Chrome ранее).Единственный результат, который я здесь получаю:

done myConnector.js:97:5
[]
​
length: 0
​
<prototype>: Array []

Все остальные console.log не запускаются.

Также Firefox жалуется на CORS, это известно, потому что я уже исправил сервер заголовков CORS-боковая сторона. Но, тем не менее, в конце получает и заполняет данные для симулятора, который я использую (см. URL выше)!Очевидно, я что-то здесь неправильно понимаю ...

Ответы [ 3 ]

0 голосов
/ 09 февраля 2019

Попробуй это.Не работает в IE.Для поддержки кросс-браузеров используйте обычный цикл for.

for (var object of response) {
    console.log(object.id);
    console.log(object.name);
}

Регулярный для

var len = response.length;

for ( var i = 0; i < len; i++ ) {
    var currentObject = response[i];

    console.log(currentObject.id);
    console.log(currentObject.name);
}

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

0 голосов
/ 09 февраля 2019

ОК, это на меня и непонимание Ajax и асинхронный запрос.Комментарии к моему вопросу помогли увидеть проблему.

Как указано выше, я вызываю этот скрипт с другого сервера (http://tableau.github.io/webdataconnector/Simulator/). Сценарий сам отправляет запрос на третий сервер.

Принудительная синхронная работа функции ajaxработает:

    $.ajax({
        url: apiUrl,
        type: 'GET',
        crossDomain: true,
        cache: false,
        async: false,

        ...})

Теперь консоль показывает массив как фактически заполненный:

(790) [empty × 123, "Name1", empty × 123, "Name2", empty × 333, "Name3"]
123: "Name1"
456: "Name2"
789: "Name3"
length: 929
__proto__: Array(0)

Итак, наконец, речь идет не о неправильной ссылке на массив / объект, а об асинхронном вызове.

0 голосов
/ 09 февраля 2019

Вы можете попробовать инициализировать определения как объект, а не как массив, т.е.var definitions = {} и идентификаторы его свойств.Так что вы можете легко пройти через него с помощью цикла for..in.

Поскольку AJAX-вызов асинхронный, журнал может выполняться на пустом массиве definitions.

for (id in definitions) {
// Logic
}
var len = Object.keys(definitions).length
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...