Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/419.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript setTimeout()如何在JS上工作_Javascript_Settimeout - Fatal编程技术网

Javascript setTimeout()如何在JS上工作

Javascript setTimeout()如何在JS上工作,javascript,settimeout,Javascript,Settimeout,只要学习JS。 在我看来,函数setTimeout代码区应该正常工作,但它不是,exp: var result = 0; (function (i){ if(i > 0){ result = result + i; i = i - 1; setTimeout("arguments.callee(" + i + ")",100);//arguments.callee(i); } else if(i == 0) return; }(10)); alert(res

只要学习JS。 在我看来,函数setTimeout代码区应该正常工作,但它不是,exp:

var result = 0;
(function (i){
if(i > 0){
    result = result + i;
    i = i - 1;
    setTimeout("arguments.callee(" + i + ")",100);//arguments.callee(i);
}
else if(i == 0)
    return;
}(10));
alert(result);
我希望它是55而不是10,如果删除setTimeout,它会很好。
有人知道为什么吗?

因为
setTimeout
是异步的,简单来说就是说它被安排在以后执行。JS不会等待它(不会在该行停止代码),而是运行后续代码

因此,当您稍后进行设置时,代码将继续在“超时循环”之外并进入警报。在此期间,循环只进行了一个循环,
result
只增加了10

您可以做什么:

  • 你可以
  • 或者,在循环完成时执行
  • 。你可以给自己的生活命名,让超时时间来调用它
试试看

var result = 0;
(function (i, callback) {
    if (i > 0) {
        result = result + i;
        i = i - 1;
        var callee = arguments.callee;
        setTimeout(function () {
            callee(i, callback)
        }, 100);
    } else if (i == 0) {
        callback();
    }
}(10, function () {
    alert(result);
}));
演示:

为什么?
您的方法中存在多个问题

  • setTimeout是异步的,这意味着您的警报将在添加操作完成之前触发-解决方案是使用回调方法,该方法将在添加操作完成后执行,如上所示

  • 当您将字符串传递给
    setTimeout
    时,它将在全局范围内执行,即
    参数。被调用方将引用与您预期不同的对象
  • 鉴于:

  • arguments.callee不受欢迎(且未弃用)
  • 命名函数表达式
  • 这里的目标似乎是不创建全局变量来运行超时
  • 考虑在IIFE中声明函数(根据我认为您需要的进行调整-10次迭代后的警报显示结果为10):

    请注意,不需要else块(除非您希望返回未定义的
    以外的内容)

    哦,请注意,在ES5和其他支持它的浏览器(不是IE<9)中,您可以在调用setTimeout时传递参数:

      setTimeout(foo, 100, --j);
    

    因此,您保存了一个额外的函数对象。

    参数。被调用方
    未被弃用,但在严格模式下是禁止的。
      setTimeout(foo, 100, --j);