内部 $.getJSON 不会转到循环中的第二个元素

Inner $.getJSON won't go to second element in loop

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"

发生了两件事:

  • $.getJSON() 是部分异步的。这意味着您的回调是异步发生的。
  • var 声明的变量的作用域是函数,而不是块,虽然你可以 re-declare 使用 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);
        });
    }
});