0

この種の例をオンラインで他に見つけることができないので、私は (もう一度) この素晴らしいコミュニティに目を向けました。

この関数 (および他の多くの関数) が連携して動作するように設計されていることをすべて述べて、この質問を過度に複雑にするつもりはありませんが、この関数 (eventDayPlotter) は毎月毎日繰り返されると言います。次のスニペットに含まれる結果がわかりません。

function eventDayPlotter(day, gridMod, monthAdjust)
{
    //Beginning of event day plotting.
    isAnEvent = false;

    $.getJSON("/JsonControl/Events.json", function (jsonObj) 
    {
        for (var i = 0; i < jsonObj.events.length; ++i) 
        {
            if(day == jsonObj.events[i].dateNumber && (navDate.getMonth() + monthAdjust) == (jsonObj.events[i].dateMonth -1) && navDate.getFullYear() == jsonObj.events[i].dateYear)
            {
                document.getElementById("cGrid" + gridMod).className="eventDay";
                console.log(jsonObj.events[i].title)
                document.getElementById("cGrid" + gridMod).onmousedown = function(){document.getElementById("eventBox").src="/Event htms/Event.htm"; document.getElementById("eventBox").document.getElementById("title").innerHTML = jsonObj.events[i].title;}
                isAnEvent = true;
            }
        }
    });
    if(isAnEvent == true)
    {
        console.log("true")
    }
    if(isAnEvent == false)
    {
        console.log("false")
    }
}

console.log の結果 (全体)

33false _main.js:1708
Okmulgee Public Schools County Professional Day _main.js:1696
Okmulgee Public Schools Starts 3rd Quarter _main.js:1696
Okmulgee Public Schools-Closed in Observance of Martin Luther King Jr. Holiday 

最初の if ブランチは 3 回実行されると予想されますが、ご覧のとおり、診断 if ブランチ (console.logs を含むブランチ) が $.getJSON 関数の外にある場合は 1 回です (ここで、意味のあるコンテンツが含まれていれば、論理的にそうである必要があります) isAnEvent は常に false です。範囲外ではないので、理解できません(私の知る限り)。

また、ファイルの後の行が最初に (他の 3 行の前に) console.log でログに記録されるとは思いませんが、この関数が逆方向に実行されているように見えますか? つまり、それが真実ではないことはわかっていますが、どうしてこれができるのでしょうか? 私は完全に途方に暮れています...

最初の if ブランチ内またはそのすぐ外側 (まだ .getJSON 関数内) で isAnEvent をテストする場合、その値は必ずしも本来あるべき値とは限りません (論理的に行く必要がある場所ではないため)。ただし、常に false であるとは限りません。ただし、一度 .getJSON 関数の外に出ると、たとえ true に変わったとしても、常に false になります。

明らかに、私には理解できない何かがここで起こっています。

最後に、明らかでない場合のために、3 つのことを示します。

1) JSON データを問題なく取得しています。

2) 最初の if ブランチは、json ファイルのいずれかの日付がその日付と一致する場合に isAnEvent を true に設定することになっています。次に eventDayPlotter が呼び出されたときに、isAnEvent を false にリセットし、次の日付 (引数で渡される) を同じ方法でテストする必要があります。

3) コンソールに表示されるスクリプト エラーはありません。

さらに情報が必要な場合はお知らせください。

4

1 に答える 1

3

getJSON()非同期です。つまり、完了して、完了後しばらくしてから完了関数を呼び出しますeventDayPlotter()

isAnEventしたがって、完了関数内の値のみをテストできます。の最後でテストしている場所でその値をテストすることはできませんeventDayPlotter()


i参考までに、次のように自己実行関数クロージャにキャプチャすることで、イベントハンドラの値を修正できます。

function eventDayPlotter(day, gridMod, monthAdjust)
{
    //Beginning of event day plotting.
    isAnEvent = false;

    $.getJSON("/JsonControl/Events.json", function (jsonObj) 
    {
        for (var i = 0; i < jsonObj.events.length; ++i) 
        {
            if(day == jsonObj.events[i].dateNumber && (navDate.getMonth() + monthAdjust) == (jsonObj.events[i].dateMonth -1) && navDate.getFullYear() == jsonObj.events[i].dateYear)
            {
                document.getElementById("cGrid" + gridMod).className="eventDay";
                console.log(jsonObj.events[i].title)
                (function(index) {
                    document.getElementById("cGrid" + gridMod).onmousedown = function(){document.getElementById("eventBox").src="/Event htms/Event.htm"; document.getElementById("eventBox").document.getElementById("title").innerHTML = jsonObj.events[index].title;}
                })(i);
                isAnEvent = true;
            }
        }
    });
}
于 2013-01-07T21:11:59.363 に答える