Внутренний $ .getJSON не перейдет ко второму элементу в цикле - PullRequest
0 голосов
/ 06 июля 2019

array1 равно ["orange","blue"].

$.getJSON("path1.json",function(array1){
    for (var i = array1.length - 1; i >= 0; i--) {
        var path2 = array1[i];
        console.log(path2);
        $.getJSON(path2,function(someObject){
            console.log("Inside the second $.getJSON function");
            console.log(path2);
        });
    }
});

Вывод выглядит следующим образом.

"orange"
"blue"
"Inside the second $.getJSON function"
"blue"
"Inside the second $.getJSON function"
"blue"

Почему вывод не такой?

"orange"
"Inside the second $.getJSON function"
"orange"
"blue"
"Inside the second $.getJSON function"
"blue"

1 Ответ

1 голос
/ 07 июля 2019

Происходят две вещи:

  • $.getJSON() частично асинхронный. Это означает, что ваши обратные вызовы происходят асинхронно.
  • Переменные, объявленные с var, относятся к функции, а не к блоку, и, хотя вы можете повторно объявить переменную в заданной области, используя var, это не имеет никакого эффекта.

Когда вы объединяете эти вещи, вы в конечном итоге сталкиваетесь с ситуацией, когда все итерации цикла for завершаются до того, как будет вызван какой-либо из обратных вызовов, и поэтому, к моменту обратного вызова, path2 было обновлено несколько раз. раз. (По совпадению, это на самом деле не влияет на внутренний вызов $.getJSON(), так как path2 передается по значению.)

В старые времена нам приходилось фиксировать область значения path2 (обычно через IIFE ), чтобы оно не перезаписывалось до выполнения обратного вызова:

$.getJSON("path1.json", function(array1){
    for (var i = array1.length - 1; i >= 0; i--) {
        var path2 = array1[i];
        console.log(path2);
        $.getJSON(path2,
            function(path2) {
                return function(someObject){
                    console.log("Inside the second $.getJSON function");
                    console.log(path2);
                };
            }(path2)
        );
    }
});

В наши дни у нас есть let, который определяет переменные для блока. Область действия блока for создается новой на каждой итерации, и этот экземпляр области привязывается к обратному вызову каждый раз, когда создается функция обратного вызова, поэтому работает следующее:

$.getJSON("path1.json",function(array1){
    for (var i = array1.length - 1; i >= 0; i--) {
        let path2 = array1[i];
        console.log(path2);
        $.getJSON(path2, function(someObject){
            console.log("Inside the second $.getJSON function");
            console.log(path2);
        });
    }
});
...