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

时间:2016-03-14 22:18:36

标签: javascript html html5 local-storage session-storage

我编写了一个JavaScript循环,应该获得8个array并按特定顺序将它们存储在localStorage中。它有效,但顺序有些混乱:localStorage中的一个键全部“向下移动”,即最后一个值被放入第一个键,第一个值被放入第二个键键,依此类推。我尝试了for循环和“自建”循环,两者都给出了相同的结果。这是代码,我将在底部做更多解释。

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中值的顺序的解决方案吗?我可以根据需要发布更多代码/解释。

干杯。

~DM

1 个答案:

答案 0 :(得分:1)

正如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);