JavaScript 循环输出顺序不正确 - 如何解决这个问题?

JavaScript loop output not in correct order - how to fix this?

我写了一个 JavaScript 循环,应该得到 8 arrays 并按特定顺序将它们存储在 localStorage 中。它有效,但是顺序有点乱:值都是 "shifted down" localStorage 中的一个键,即最后一个值被放入第一个键,第一个值被放入第二个键,依此类推。我已经尝试了 for 循环和 "self-built" 循环,它们都给出了相同的结果。这是代码,我会在底部做更多的解释。

var i = -1;

function getstats() {
    i = i + 1;
    if (i > -1 && i < 9) {
        var ids = document.getElementById("battle_deck_block_" + i).getElementsByTagName("img")[0].id;

        var tribe;
        if (ids < 117603 && ids > 100000) {
            tribe = "Xana";
        } else if (ids < 213403 && ids > 200000) {
            tribe = "Hemi";
        } else {
            tribe = "Theri";
        }

        var referenceurl = "Dot_files/Trade/" + tribe + "/" + ids + ".js";

        var temp = document.createElement("SCRIPT");
        var src = document.createAttribute("src");
        src.value = referenceurl;
        temp.setAttributeNode(src);
        document.head.appendChild(temp);

        var hp = sessionStorage.getItem("minhp");
        var atk = sessionStorage.getItem("minatk");
        var def = sessionStorage.getItem("mindef");
        var wis = sessionStorage.getItem("minwis");
        var agi = sessionStorage.getItem("minagi");

        var stats = [hp, atk, def, wis, agi];

        localStorage.setItem("fighter" + i + "_stats", JSON.stringify(stats));

        document.head.removeChild(temp);

    } else if (i > 8 || i < 0) {
        return;
    };
};
setInterval(getstats, 200);

所以基本上这是一个为我正在为游戏开发的战斗系统获取角色统计数据的函数。 该函数基于字符的 id 构建一个引用 URL,并将其设置为 src 用于同样在函数中创建的 script 标签(此标签在后面为每个循环删除和重新创建)。 script 标签中使用的每个源文件都是一个 JavaScript 文件,它将角色的统计数据设置为 sessionStorage 值。然后将这些值放入相应的变量中,然后将变量放入数组中并存储在 localStorage 中以备后用。 现在,正如我之前提到的,除了 localStorage 值的顺序外,这一切都工作得很好。这是我寻求帮助的地方。

有人可以查看我的代码并提出一个可以修复 localStorage 中值顺序的解决方案吗?我可以根据需要 post 更多 codes/explanations。

干杯。

~私信

正如 Pointy 所提到的,您的问题是在 运行 调用 localStorage 代码之前,代码不会暂停以等待获取的脚本被下载和执行。这意味着此脚本第一次 运行 时,sessionStorage 值将为空,第一个循环将为空,第二个循环将具有第一个脚本的值,依此类推。当您第二次 运行 脚本时,前一个 运行 的最后一个值在 sessionStorage 中,因此第一个键获取最后一个值,等等

您可以通过 (1) 使用脚本标记的 onload 事件,以及 (2) 使用闭包冻结脚本的 i 状态来解决此问题(因为它会随着循环而变化续)。

var i = -1;

function getClosure(i, temp) {
    // Inside this closure, the current values of i and temp are preserved.
    return function() {
        var hp = sessionStorage.getItem("minhp");
        var atk = sessionStorage.getItem("minatk");
        var def = sessionStorage.getItem("mindef");
        var wis = sessionStorage.getItem("minwis");
        var agi = sessionStorage.getItem("minagi");

        var stats = [hp, atk, def, wis, agi];

        localStorage.setItem("fighter" + i + "_stats", JSON.stringify(stats));

        document.head.removeChild(temp);
    }
}

function getstats() {
    i = i + 1;
    if (i > -1 && i < 9) {
        var ids = document.getElementById("battle_deck_block_" + i).getElementsByTagName("img")[0].id;

        var tribe;
        if (ids < 117603 && ids > 100000) {
           tribe = "Xana";
        } else if (ids < 213403 && ids > 200000) {
           tribe = "Hemi";
        } else {
           tribe = "Theri";
        }

        var referenceurl = "Dot_files/Trade/" + tribe + "/" + ids + ".js";

        var temp = document.createElement("SCRIPT");
        var src = document.createAttribute("src");
        src.value = referenceurl;
        temp.setAttributeNode(src);
        // The function returned by getClosure() will be executed after this script loads
        temp.onload = getClosure(i, temp);
        document.head.appendChild(temp);

    } else if (i > 8 || i < 0) {
        return;
    };
};
setInterval(getstats, 200);