简体   繁体   English

关于javascript setTimeout异步模式

[英]About javascript setTimeout asynchronous mode

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
        var i = 0;
        var d = 0;
        function BBB() {
            i++;
            alert("11");
            if (i <= 10)
                setTimeout("BBB()", 300);
        }
        function HHH() {
            d++;
            alert("22");
            if (d<= 10)
                setTimeout("HHH()", 300);
        }
        function CCC() {
            BBB();
            HHH();
        }
    </script>
</head>
<body>
    <input type="button" value="Submit" onclick="CCC()"/>
</body>
</html>

I would like to execute BBB function completely,then HHH function. 我想完全执行BBB功能,然后执行HHH功能。 But the result is not so.The output is 11 22 11 11...... 但结果并非如此,输出为11 22 11 11......

How to solve this?Sorry for my poor english! 该如何解决?对不起我的英语不好! Thanks! 谢谢!

setTimeout causes the functions to not be sequentially executed. setTimeout导致这些功能无法顺序执行。

You would do what you do in any other asynchronous context ie 您将在任何其他异步上下文中进行操作,即

  • Pass the function names as callback names 将函数名称作为回调名称传递
  • Keep a global variable to keep track 保持全局变量以保持跟踪
  • Use events. 使用事件。

In your case you have a variable i keeping track of the calls & hence Like this, perhaps : 在您的情况下,您有一个变量i跟踪呼叫,因此像这样,也许:

 <script type="text/javascript">
        var i = 0;
        var d = 0;
        function BBB() {
            i++;
            alert("11");
            if (i <= 10)
                setTimeout("BBB()", 300);
            else HHH();
        }
        function HHH() {
            d++;
            alert("22");
            if (d<= 10)
                setTimeout("HHH()", 300);
        }
        function CCC() {
            BBB();
        }
    </script>

Saw you tagged this with so here is a prettty elegant way to do this using the power of jQuery. 看到您用标记了它,因此这是一种使用jQuery强大功能的漂亮方法。

var deferredObj = $.Deferred();
var counter1 = 0;  
var counter2 = 0;  
function First() {
    counter1++;
    alert("first - " + counter1);
    if (counter1 >=3) {
        deferredObj.resolve();
        return;
    }
    setTimeout(First, 300);
}

function Second() {
    counter2++;
    alert("second - " + counter2);
    if (counter2 >= 3)
        return;
    setTimeout(Second, 300);
}

First();
deferredObj.done(function(){
    Second();
});

The key here is marking the deferred object as "resolved" when first method finish, then jQuery knows it can execute the second method. 这里的关键是在第一个方法完成时将延迟对象标记为“已解决”,然后jQuery知道它可以执行第二个方法。 Credits for this way belong to Kevin in this answer . 这种方式的荣誉属于凯文在这个答案中

Live test case . 现场测试用例

An optimized version of a function that runs a set of functions in their order. 函数的优化版本,按其顺序运行一组函数。

var runner = function(fn) {
    var counter = 10, delay = 300;
    setTimeout(function run(){
        fn[0].apply(this);
        counter--;
        counter && setTimeout(run, delay);
        !counter && fn.shift() && fn.length && runner(fn);
    }, delay);
};

You can use it as follows: 您可以按以下方式使用它:

var log = function(text){
    return function(){
        console.log(text);
    };
};

runner([ log("1"), log("2"), log("3") ]);

A live example. 一个真实的例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM