javascript 我可以在另一个 setTimeout 中设置一个 setTimeout 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13887186/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 20:03:16  来源:igfitidea点击:

can I have a setTimeout inside another setTimeout?

javascriptsettimeout

提问by ttothec

Here's a quick (broke) jsfiddle: http://jsfiddle.net/wH2qF/

这是一个快速(坏了)jsfiddle:http: //jsfiddle.net/wH2qF/

This isn't working for some reason... is it because I have a setTimeout inside another setTimeout?

这出于某种原因不起作用......是因为我在另一个 setTimeout 中有一个 setTimeout 吗?

$(function() {
   $("#Volume").click(function() {
      setTimeout(triggerVolumeChange, 4000);
      function triggerVolumeChange() 
      {
          var volumeDiv = document.getElementById("volumeNumber");
          var volumeOld = 8;
          var volumeNew = 37;
          var timeNew = (1000/(volumeNew-volumeOld));
          changeVolume();

          function changeVolume()
          {
             volumeDiv.innerHTML = volumeOld;
             volumeOld++;
             if (volumeOld <= volumeNew) setTimeout(changeVolume, timeNew);
          };
      });
});

Should specify that for clarity purposes I deleted other things from that Click function, and also to clarify what doesn't work exactly, well, basically, I click and nothing happens, whereas if I cut out this chunk of code it works fine... actually the setting of the vars also work fine (naturally I presume) but when I paste or uncomment the changeVolume() function then the click stops working again... Any thoughts?

应该指出,为了清晰起见,我从该 Click 函数中删除了其他内容,并澄清了哪些内容不起作用,基本上,我单击并没有任何反应,而如果我删除了这段代码,它就可以正常工作.. . 实际上 vars 的设置也可以正常工作(我自然认为)但是当我粘贴或取消注释 changeVolume() 函数时,单击再次停止工作......有什么想法吗?

--

——

Another piece of clarification: What I'm trying to do is, on click, simulate the volume going from value 8 to 37, in a string.. thus the setTimeout inside that function.

另一条说明:我想要做的是,在单击时,模拟字符串中从值 8 到 37 的音量..因此该函数内的 setTimeout 。

--

——

As per your guy's request, here's the entire code... I doubt it will make sense, but here it is... FYI, on click this will trigger a number of animations to simulate the flow of an application I'm designing..

根据你的家伙的要求,这里是整个代码......我怀疑它是否有意义,但这里是......仅供参考,点击这将触发一些动画来模拟我正在设计的应用程序的流程。 .

<script>
            $(function() {
                $("#Volume").click(function() {

                    var userPrompt = document.getElementById("userPrompt")
                    userPrompt.innerHTML = "Change volume to 37";

                    var avatarIcon = document.getElementById("avatarIcon");
                    avatarIcon.innerHTML = "<img src='imgs/haloIcons-volume_82x76.png' alt='Volume'/>";

                    var hints = document.getElementById("hints");
                    hints.style.opacity = 0;
                    $(".dragonTvOut").toggleClass("dragonTvIn");

                    setTimeout(triggerP, 1000);
                    function triggerP()
                    {
                        var halo = document.getElementById('avatar');
                        if( 'process' in halo ) { 
                            halo.process();
                        };
                    };

                    setTimeout(triggerUserPrompt, 2000);
                    function triggerUserPrompt() 
                    {
                        document.getElementById("userPrompt").className = "userPromptIn";
                    };

                    setTimeout(triggerVolumeChange, 4000);
                    function triggerVolumeChange() 
                    {
                        document.getElementById("userPrompt").className = "userPromptEnd";

                        var halo = document.getElementById('avatar');
                        if( 'resume' in halo ) { 
                            halo.resume();
                        }

                        document.getElementById("avatarIcon").className = "avatarIconEnd";

                        var volumeDiv = document.getElementById("volumeNumber");
                        var volumeOld = 8;
                        var volumeNew = 37;
                        var timeNew = (1000/(volumeNew-volumeOld));
                        changeVolume();

                        function changeVolume()
                        {
                            volumeDiv.innerHTML = volumeOld;
                            volumeOld++;
                            if (volumeOld <= volumeNew) setTimeout(changeVolume, timeNew);
                        }?;

                        var side = 100;
                        var paper = new Raphael(volumeArcAnim, 100, 300);

                        paper.customAttributes.arc = function (xloc, yloc, value, total, R) {

                            var alpha = 360 / total * value,
                                a = (90 - alpha) * Math.PI / 180,
                                x = xloc + R * Math.cos(a),
                                y = yloc - R * Math.sin(a),
                                path;
                            if (total == value) {
                                path = [
                                    ["M", xloc, yloc - R],
                                    ["A", R, R, 0, 1, 1, xloc - 0.01, yloc - R]
                                ];
                            } else {
                                path = [
                                    ["M", xloc, yloc - R],
                                    ["A", R, R, 0, +(alpha > 180), 1, x, y]
                                ];
                            }
                            return {
                                path: path
                            };
                        };

                        var arcWidth = 87;
                        var strokeRadius = arcWidth/2;

                        var indicatorArc = paper.path().attr({
                            "stroke": "#ffffff",
                            "stroke-width": 3,
                            arc: [side/2, side/2, 12, 100, strokeRadius]
                        });

                        indicatorArc.animate({
                            arc: [side/2, side/2, 60, 100, strokeRadius]
                        }, 1500, "<>", function(){
                            // anim complete here
                        });

                    };

                });
            });
            </script>

回答by Sirko

You're missing an }:

你缺少一个}

$(function() {
   $("#Volume").click(function() {
      setTimeout(triggerVolumeChange, 4000);
      function triggerVolumeChange()
      {
          var volumeDiv = document.getElementById("volumeNumber");
          var volumeOld = 8;
          var volumeNew = 37;
          var timeNew = (1000/(volumeNew-volumeOld));
          changeVolume();

          function changeVolume()
          {
             volumeDiv.innerHTML = volumeOld;
             volumeOld++;
                 if (volumeOld <= volumeNew) setTimeout(changeVolume, timeNew);
          };
      } // that one was missing
   });
});

回答by Juan Mendes

In your broken example http://jsfiddle.net/wH2qF/there are a few problems

在你的坏例子http://jsfiddle.net/wH2qF/有一些问题

  • You forgot to tell jsfiddle to use jQuery
  • The id of the volume span (in JS) was phbut should be volumeNumber(as in the HTML)
  • 你忘了告诉 jsfiddle 使用 jQuery
  • 卷跨度的 id(在 JS 中)是ph但应该是volumeNumber(如在 HTML 中)

Click here to see a working version

单击此处查看工作版本

Had you selected jQuery from the libraries in jsfiddle, you would have seen an error

如果你从 jsfiddle 的库中选择了 jQuery,你会看到一个错误

Uncaught TypeError: Cannot set property 'innerHTML' of null

未捕获的类型错误:无法设置 null 的属性“innerHTML”

That leads me to believe that your jsfiddle is not a good representation of your problem. Maybe try to create another reduction since the one you added only had "silly" errors?

这让我相信您的 jsfiddle 不能很好地代表您的问题。也许尝试创建另一个减少,因为您添加的那个只有“愚蠢”的错误?

回答by Spudley

Yes, you can have a setTimeout()inside another one -- this is the typical mechanism used for repeating timed events.

是的,您可以setTimeout()在另一个内部有一个 - 这是用于重复定时事件的典型机制。

The reason yours isn't working is not to do with the setTimeout()itself; it's to do with the way you've nested the functions.

你的不工作的原因与它setTimeout()本身无关;这与您嵌套函数的方式有关。

The changeVolume()function being inside triggerVolumeChange()means that you can't reference it directly using its name.

changeVolume()函数内部是triggerVolumeChange()意味着你不能直接使用它的名字引用它。

The quickest solution for you would be to remove the nesting, so that changeVolume()is at the root level rather than nested inside triggerVolumeChange().

对您来说最快的解决方案是删除嵌套,因此它changeVolume()位于根级别而不是嵌套在triggerVolumeChange().

回答by Teemu

If you don't want to use setInterval(), you can make the code work with these changes:

如果您不想使用setInterval(),您可以使代码使用这些更改:

$(function() {
    $("#Volume").click(function() {
        setTimeout(triggerVolumeChange, 4000);
        function triggerVolumeChange () {
            var volumeDiv = document.getElementById("volumeNumber");
            var volumeOld = 8;
            var volumeNew = 37;
            var timeNew = (1000/(volumeNew-volumeOld));
            var changeVolume = function () {
                volumeDiv.innerHTML = volumeOld;
                volumeOld++;
                if (volumeOld <= volumeNew) setTimeout(changeVolume, timeNew);
            };
            changeVolume();
        }
    });
});

Working demo at jsFiddle.

jsFiddle 的工作演示。