JSON取得時にカウントアップした変数の値をその後の処理に引き継ぎたい
いつもお世話になっております。javascript初心者です。  
前回、ajaxのsuccess時に、さらにjsonを呼び出す方法を学んだんですが、  
今度はjson内でのカウントアップした値をjsonを抜けたあとに引き継ぎをしたいのですが、なぜかうまく行きません。

お手数おかけしますが、ご教授お願い致します。

現在の結果 → alert(j);  
alert 0  
alert 0  
alert 0  
alert 0  
alert 0  
alert 0  
alert 0  
alert 0

求める結果 → alert(j);

alert 0  
alert 1  
alert 2  
alert 3  
alert 4  
alert 5  
alert 6  
alert 7

```

    function Henka() {
    
        $.ajax({
            url: 'CSVのアドレス',
            success: function (era) {
    
                // csvのjson
                csvListall = $.csv()(era);
    
                // 変数jの定義
                var j = 0;
    
                //for分を追加して
                for (var i = 0; i < 264; i++) {
    
                    //各変数定義;
                    var calendarId = '';
                    var calendarId = csvListall[i][2];
                    var irank = '';
                    var irank = csvListall[i][5];
                    var iimg = '';
                    var iimg = csvListall[i][7];
                    var iname = '';
                    var iname = csvListall[i][0];
                    var itarget = '';
                    var itarget = csvListall[i][6];
    
                    var tab = '[data-today="' + j + '"]';
                    var uri = "https://www.googleapis.com/calendar/v3/calendars/" + calendarId + "/events?key=" + apikey + "&timeMin=" + timeMin + "&timeMax=" + timeMax + "&maxResults=10&orderBy=startTime&singleEvents=true";
                    var jsinfo = uri;
    
                    //問題のポイントは下記から-------------------------------------------
    
                    $.getJSON(jsinfo,
                        (function (irank, iimg, iname, tab, itarget, j) {
                            return function (data) {
                                if (data.items[0].summary != "") {
                                    //処理回数カウント
                                    j = j + 1;
                                    //処理内容
                                    vivid = '<img src="' + iimg + '" alt="empty" style="height: 150px;" class="app-button" data-target="' + itarget + '"><br>' + iname + '';
                                    $(tab).append(vivid);
                                }
                            };
                        })(irank, iimg, iname, tab, itarget, j)
                    );
                    alert(j);
    
                    //問題のポイントは上記まで-------------------------------------------
    
                }
            }
        });
    }
    
```
**回答**

おそらく下記のようにすれば、JSONのダウンロードが完了した順に`[data-
today="0"]`～`[data-t‌​oday="263"]`にimgタグが追加されていくかと思います。

`[data-today="1"]`からスタートする場合、変数jの初期値を1にしてください。  
(`var j = 1;`に変更する)

```

    function Henka() {
        $.ajax({
            url: 'CSVのアドレス',
            success: function (era) {
                // csvのjson
                csvListall = $.csv()(era);
    
                // 変数jの定義
                var j = 0;
    
                //for文を追加して
                for (var i = 0; i < 264; i++) {
    
                    //各変数定義
                    var calendarId = csvListall[i][2];
                    var irank      = csvListall[i][5];
                    var iimg       = csvListall[i][7];
                    var iname      = csvListall[i][0];
                    var itarget    = csvListall[i][6];
    
                    var uri = "https://www.googleapis.com/calendar/v3/calendars/" + calendarId + "/events?key=" + apikey + "&timeMin=" + timeMin + "&timeMax=" + timeMax + "&maxResults=10&orderBy=startTime&singleEvents=true";
    
                    $.getJSON(uri,
                        (function (iimg, iname, itarget) {
                            return function (data) {
                                if (data.items[0].summary !== "") {
                                    //処理内容
                                    var tab = '[data-today="' + j + '"]';
                                    var vivid = '<img src="' + iimg + '" alt="empty" style="height: 150px;" class="app-button" data-target="' + itarget + '"/><br/>' + iname;
                                    $(tab).append(vivid);
    
                                    //処理回数カウント
                                    j = j + 1;
                                }
                            };
                        })(iimg, iname, itarget)
                    );
                }
            }
        });
    }
    
```

**解説**

`//処理内容`の`j`はfor文の上に定義している`var j = 0;`の値を参照します。  
なので、JSONのダウンロードが終わるたびに`//処理回数カウント`が実行されて、数値が1ずつ大きくなっていきます。

自分自身の外側に定義されている変数を参照している関数は、[クロージャ](https://developer.mozilla.org/ja/docs/Web/JavaScript/Closures)と呼ばれます。

今回の例では外側に定義されている変数が`j`で、`j`を参照している`//処理内容`がある関数がクロージャです。

以下は質問にあるコードで気になった点です。

  * `var irank`等、2回定義している箇所がありますが、1回目の直後の2回目で値を代入しているので、1回目の定義は不要です。  
(変数の定義(`var`)は1度だけ行うようにした方がよいです)

  * `//処理内容`で`irank`は使用されていないので、`(function(){})()`に渡す必要はありません。
  * `vivid`はローカル変数かと思いますので、`var`を付けたほうがよいです。
  * 一般的に値の比較は`===`や`!==`を使用したほうがよいです。

[比較演算子 - JavaScript |
MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Identity)

**余談**

回答に書いたコードと同じような動作をする最小のコードを以下に作成しました。  
興味があればご覧ください。

```

    var csvListall = [
      [0, "sss", "//dummyimage.com/101x50/", "one", "target"],
      [1, "ss", "//dummyimage.com/102x50/", "two", "target"],
      [2, "s", "//dummyimage.com/103x50/", "three", "target"],
      [3, "a", "//dummyimage.com/104x50/", "four", "target"],
      [4, "b", "//dummyimage.com/105x50/", "five", "target"],
      [5, "c", "//dummyimage.com/106x50/", "six", "target"],
      [6, "sss", "//dummyimage.com/107x50/", "seven", "target"],
      [7, "ss", "//dummyimage.com/108x50/", "eight", "target"],
      [8, "s", "//dummyimage.com/109x50/", "nine", "target"],
      [9, "a", "//dummyimage.com/110x50/", "ten", "target"]
    ];
    
    var j = 0;
    
    for (var i = 0; i < 10; i++) {
      var calendarId = csvListall[i][0];
      var rank = csvListall[i][1];
      var img = csvListall[i][2];
      var name = csvListall[i][3];
      var target = csvListall[i][4];
    
      // 非同期処理 (JSONのダウンロードを想定)
      setTimeout((function(img, name, target) {
        return function(data) {
          if (Math.random() > 0.5) {
            //処理内容
            var vivid = '<img src="' + img + '" alt="empty" data-target="' + target + '"/><br/>' + name;
            $('[data-today="' + j + '"]').append(vivid);
            j++;
          }
        }
      })(img, name, target), 500);
    }
```

```

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <div data-today="0"></div>
    <div data-today="1"></div>
    <div data-today="2"></div>
    <div data-today="3"></div>
    <div data-today="4"></div>
    <div data-today="5"></div>
    <div data-today="6"></div>
    <div data-today="7"></div>
    <div data-today="8"></div>
    <div data-today="9"></div>
```

0～1の値をランダムに生成する`Math.random()`の値が0.5より大きかった場合、imgタグを追加する処理が動くようになっています。