使用揭示模块模式的 setTimeout

4

在JavaScript的模块模式中如何使用setTimeout函数?

这里是示例

HTML:<div id="container1"></div>

JavaScript:

var classA = (function() {
    var i = 0;
    var names = ["a", "b", "c", "d", "e", "f"];
    var callTest = function() {
        for (var n in names) {
            window.setTimeout(function() {
                callTest2(names[n]);
            }, 1000);
        }
    };

    var callTest2 = function(pName) {
        $("#container1").append("In callTest   " + i+++" " + pName + "<br>");
        window.setTimeout(function() {
            callTest2(pName)
        }, 10000)
    };

    return {
        testTheTest: function() {
            callTest();
        }
    }
})();

classA.testTheTest();

框架:jQuery 1.5.2

执行后的输出结果为:

In callTest 0 f
In callTest 1 f
In callTest 2 f
In callTest 3 f
In callTest 4 f
In callTest 5 f

改为:

In callTest 0 a
In callTest 1 b
In callTest 2 c
In callTest 3 d
In callTest 4 e
In callTest 5 f

我错过了什么?我做错了什么?


感谢您提供JS Patterns的链接,已点赞 :) - Jamie Hutber
3个回答

2

我对你的代码进行了一些微小的修改,这意味着它现在可以按照你的意愿正常工作:

var classA = (function() {
    var i = 0,
        names = ["a", "b", "c", "d", "e", "f"],
        namesLength = names.length,
        callTest = function() {
            window.setTimeout(function() {
                callTest2(0);
            }, 1000);
        },
        callTest2 = function(pIndex) {
            if (pIndex < namesLength) {
                var name = names[pIndex++];
                $("#container1").append("In callTest   " + i+++" " + name + "<br>");
                window.setTimeout(function() {
                    callTest2(pIndex);
                }, 1000);
            }
        };

    return {
        testTheTest: function() {
            callTest();
        }
    }
})();

classA.testTheTest();

这里有一个涉及IT技术的实际例子

1
如果您列出了您所做更改的“原因”,那将会很有帮助。 - VtoCorleone

2

因为setTimeout函数的调用不是在那个位置,而是在1秒后。当它被调用时,n等于最后一个索引。你必须将n设为全局变量,并且每次调用函数都要递增。

var classA = (function() {
    var i = 0;
    var names = ["a", "b", "c", "d", "e", "f"];
    var n = 0;
    var callTest = function() {
        for (var i in names) {
            window.setTimeout(function() {
                callTest2(names[n]);
                n++;
            }, 1000);
        }
    };

    var callTest2 = function(pName) {
        $("#container1").append("In callTest   " + i+++" " + pName + "<br>");
        window.setTimeout(function() {
            callTest2(pName)
        }, 10000)
    };

    return {
        testTheTest: function() {
            callTest();
        }
    }
})();

classA.testTheTest();

1
   for (var n in names) {
            window.setTimeout(function() {                
                callTest2(names[n]);
            }, 1000);
        }

上面的代码等同于下面的代码。

    callTest2("f");
    callTest2("f");
    callTest2("f");
    callTest2("f");
    callTest2("f");
    callTest2("f");

为什么..? 原因是在一秒完成之后调用了函数callTest2(),但在此之前整个names[]数组已经被迭代并且“f”最后一个字符被传递给函数callTest2。
for循环在非常短的微秒级别上进行迭代。即names[]数组将在非常短的时间内被迭代。 最后一个字符保留为“f”,即names[n]。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接