2 sugus awesome sugus_awesome 于 2013.09.07 16:48 提问

js延迟顺序执行的问题

现在项目中遇到一个问题。就是在前台页面顺序延迟显示后台发送的数据。
比如前台是一个表格,点击前台按钮后,一次获得table上该显示的所有随机序号。
目前的问题不能让这些选择的序号顺序延迟显示。
这个问题类似于在表格中随机点名。
代码不完整:

<table>
   <tr><td>11</td><td>12</td><td>13</td><td>14</td></tr>
   <tr><td>21</td><td>22</td><td>23</td><td>24</td></tr>
   <tr><td>31</td><td>32</td><td>33</td><td>34</td></tr>
   <tr><td>41</td><td>42</td><td>43</td><td>44</td></tr>
</table>
<input type="button" value="顺序延迟加载" id="btnRun" />
<script>
   $(function(){
       $("#btnRun").click(function(){
           // rndArray假如是产生的一个瞬间顺序数组,用来控制表格的td变色
           var rndArray=[3,7,11,1,12,15];
           for(var i=0;i<rndArray.length;i++){
               setTimeout(function(){
                   $("table td").eq(i).addClass("test1").siblings().removeClass("test1");
               },1000);
           }
       })
   });
</script>

今天查阅了一下js是单线程执行的,setTimeout("code()",delay)是在delay后将code插入到代码中。
因此这样肯定无法实现我要的功能。不知道有什么好方法可以实现这个功能,
以前在学习视频的时候看到过这个表格随机点名的效果。

求大神指点该怎么弄。

5个回答

j_clxy
j_clxy   2013.09.07 18:02

递增那个时间间隔不可以吗?
虽然不够精确。

for(var i=0;i<rndArray.length;i++){
    setTimeout(function(){
        $("table td").eq(i).addClass("test1").siblings().removeClass("test1");
    },1000*(i+1));
}

想要精确,就只有递归加回调了。

sugus_awesome
sugus_awesome 你说的递归回调不知道怎么写,我下面简单说下我的解决方法。
4 年多之前 回复
sugus_awesome
sugus_awesome setTimeout是在delay时间之后将code插入,所以在单线程异步的setTimeout无法很好实现。不过昨天找到了一个替代方法。
4 年多之前 回复
sugus_awesome
sugus_awesome   2013.09.08 14:40

谢谢大家帮忙想办法,昨天搜了很多方法,综合各种,最后找到一种可行的是。ajax同步调用,前台等待后台返回,后台线程sleep。这样可以解决,但希望还有更好的方法。

asiaasia666
asiaasia666   2013.09.10 22:05

本质应该是循环遍历发生了js的一个bug。解决办法看下面的例子。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
    <HEAD>
        <TITLE> 简单实验 </TITLE>
        <META NAME="Generator" CONTENT="EditPlus">
            <META NAME="Author" CONTENT="">
                <META NAME="Keywords" CONTENT="">
                    <META NAME="Description" CONTENT="">
                        <script type="text/javascript" src="jquery.js"></script>
    </HEAD>

    <BODY>

        页面报错的话,修改js路径<br/>
        <table border="1">
            <tr>
                <td>11</td>
                <td>12</td>
                <td>13</td>
                <td>14</td>
            </tr>
            <tr>
                <td>21</td>
                <td>22</td>
                <td>23</td>
                <td>24</td>
            </tr>
            <tr>
                <td>31</td>
                <td>32</td>
                <td>33</td>
                <td>34</td>
            </tr>
            <tr>
                <td>41</td>
                <td>42</td>
                <td>43</td>
                <td>44</td>
            </tr>
        </table>
        <input type="button" value="顺序延迟加载" id="btnRun" />
        <script>


           $(function(){
               $("#btnRun").click(function(){
                   // rndArray ,从0开始, 第0个为red,第5个为green,第10个为tomato,地15个为hotpink
                   var rndArray=[0,5,10,15];
                   var colorArray=['red','green','tomato','hotpink'];
                   $("#btnRun").attr('disabled',true);
                   for(var i=0;i<rndArray.length;i++){
                       setTimeout(function(i2){
                            var _i = rndArray[i2];
                            return function(){
                               $("table td").eq(_i).css('background-color', colorArray[i2]);
                            };
                       }(i),1000);
                   }
               })
           });

        </script>
    </BODY>
</HTML>
asiaasia666
asiaasia666   2013.09.07 18:24

很典型的问题,循环遍历问题。

sugus_awesome
sugus_awesome setTimeout是在delay时间之后将code插入,所以在单线程异步的setTimeout无法很好实现。不过昨天找到了一个替代方法。
4 年多之前 回复
j_clxy
j_clxy   2013.09.10 17:57

上面的内容不是你全部的需求吗?

setTimeout("code()",delay)是在delay后将code插入到代码中

这句不是很懂。

----- 递增那个时间间隔的做法如下。

var rndArray = [ 3, 7, 11, 1, 12, 15 ];
function chageColor(index) {
    console.log(index);
    $("table td").eq(index).addClass("test1");
}
$("#btnRun").click(function() {
    for ( var i = 0; i < rndArray.length; i++) {
        setTimeout("chageColor(" + rndArray[i] + ")", 1000 * (i + 1));
    }
});

---- 递归回调的做法。处理一个TD后,调用回调。而回调是层层嵌套,以实现每个处理结束后继续下个。

var rndArray = [ 3, 7, 11, 1, 12, 15 ];
function chageColor2(index, callback) {
    console.log(index);
    $("table td").eq(index).addClass("test2");
    if (callback) {
        setTimeout(callback, 1000);
    }
}
$("#btnRun").click(function() {
    var f = false;
    $(rndArray.reverse()).each(function(i, v) {
        f = (function(index, callback) {
            return function() {
                chageColor2(index, callback);
            };
        })(v, f);
    });
    f();
});
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!