【问题标题】:Javascript SetTimeout and Loops [duplicate]Javascript SetTimeout和循环[重复]
【发布时间】:2013-01-25 07:35:14
【问题描述】:

专家。 Javascript 未产生所需的延迟效果。
从其他问题中,我了解到,问题在于 settimeout 和我使用它的方式。 但我仍然无法理解 Settimeout 是如何工作的。 所以我把代码放在这里。 由于知识目的,只需要使用 Javascript。
实际上,我正在尝试在 javascript 中清除关于 this,closure 的概念。 它们是 Javascript 的一种扭曲的东西吗?

var objImg = new Object();
var h;
var w;

var no = 100;
while (no != 500) {
    setTimeout(function () {
        size(no, no);
    }, 2000);

    /* it's get executed once, instead of repeating with while loop
    Does it leave loop in mid? I get image with 500px height and
    width, but effect is not acheived.
    */

    no = no + 50;
}

function size(h, w) {
    var objImg = document.getElementsByName('ford').item(0);
    objImg.style.height = h + 'px';
    objImg.style.width = w + 'px';
}

【问题讨论】:

  • 你的while循环运行正常。我已经在chrome控制台上测试过了。
  • @ramin omrani - 是吗?但图像没有调整大小,延迟效果为 2 秒。我知道我搞砸了 SetTimeout,但还不完全了解它的内部工作原理。

标签: javascript settimeout


【解决方案1】:

你有两个问题:

  • no 在回调被调用时会有 end of loop 的值
  • 您正在编程从同一时间开始的所有超时 2000 毫秒,即循环运行的时间。

以下是您可以解决的方法:

var t = 0
while (no != 500) {
   (function(no) {
      t += 2000;
      setTimeout(function() { size(no,no);} ,t);
   })(no);
   no  = no+50; // could be written no += 50
}

立即执行的函数会创建一个作用域来保护no 的值。


关于(function(no) {的一点解释:

变量的作用域是

  • 全球范围
  • 一个函数

上面的代码可以写成

var t = 0
while (no != 500) {
   (function(no2) {
      t += 2000;
      setTimeout(function() { size(no2,no2);} ,t);
   })(no);
   no += 50;
}

这里可能更清楚我们有两个变量:

  • no,其值随着每次迭代而变化,在调用超时时为 500
  • no2,实际上每次调用内部匿名函数都会有一个变量no2

每次调用内部匿名函数时,都会声明一个新的no2变量,在调用时(迭代期间)其值为no。这个变量no2因此受到保护,并被提供给setTimeout的回调使用。

【讨论】:

  • 嗨@dystroy - 还没有成功。您的代码使浏览器无响应。
  • @msinfo 我的第一个版本是错误的(关闭时没有增加)。可以试试最后一个吗?
  • 是的,它确实有效。您能否解释一下,while 循环的两次迭代,以及 t 的值和在这些条件下没有变量。谢谢(所有这些多次编辑。:-)
  • 抱歉编辑(流感很难回答)。还需要详细解释还是说清楚了?
  • 感谢@daleyjem,我现在知道了 settimeout 的工作原理。但需要功能(无)工作的帮助。我就在那里,但我知道我错过了一些东西。
【解决方案2】:

为什么不直接使用 setInterval() 呢?

var objImg = new Object();
var h;
var w;

var no = 100;
var myInterval = window.setInterval(function() {
    size(no, no);
    no = no + 50;
    if (no >= 500) clearInterval(myInterval);
}, 2000);

function size(h, w) {
    var objImg = document.getElementsByName('ford').item(0);
    objImg.style.height = h + 'px';
    objImg.style.width = w + 'px';
}

【讨论】:

  • 嘿嘿嘿 :-) 它按你的方式工作。实际上我写了上面的测试代码来测试我对 settimeout 和其他东西的了解,在这里我学到了另一种方法。一旦有人在我的代码中解释了 settimeout 发生了什么,就会将其标记为答案。谢谢。
  • 您的代码无法按照您的想法运行,因为您认为一旦从前一个 setTimeout() 过去的时间过去,每个 setTimeout() 都会被调用。但事实并非如此。所有这些 setTimeout() 都会同时被立即调用。
  • 哦!我明白了,真的,我在想你想的那样。但是哎呀!因为@dystroy 提供了带有 settimeout 选项的解决方案,并且他多次编辑了他的答案以通知我。我接受他的回答并投票赞成你的回答。
  • 就像 dystroy 说的那样......当所有这些 setTimeout() 都被调用时(将同时调用),“no”的值将增加到500(这将在代码执行后的几毫秒内发生)。
【解决方案3】:

您的问题在于您的 size() 函数语法和算法:

var objImg = new Object();
var h;
var w;

var no = 100;

var int = window.setInterval(function () {
    size(no,no);
    no += 50;
},2000)

function size(h, w) {
    if (h == 500){
        window.clearInterval(int);
        return;
    }
    var height = h + 'px';
    var width = w + 'px';
    document.getElementsByName('ford').item(0).style.height = height;
    document.getElementsByName('ford').item(0).style.width = width;
}

http://jsfiddle.net/AQtNY/2/

【讨论】:

    猜你喜欢
    • 2013-09-15
    • 1970-01-01
    • 1970-01-01
    • 2013-10-13
    • 2014-05-18
    • 2010-12-19
    • 2016-08-30
    • 1970-01-01
    相关资源
    最近更新 更多