javascript - js 中for循环中延时执行问题
巴扎黑
巴扎黑 2017-04-11 13:11:07
0
2
1067

想实现的是用条形图动态展示排序算法

其中排序算法中交换两个数的位置会触发交换两个p,现在想把这个交换操作给hold住1s

这个效果目前只能单步调试出现,想代码给他
common.js文件:

/**
 * Created by apple on 2017/3/30.
 * 公共的js方法
 */
let commonFun = {
    /**
     * 生成length位 m~n 之间的随机数数组
     * 
     * @param  int m      [description]
     * @param  int n      [description]
     * @param  int length [description]
     * @return array        [description]
     */
    randonm :  ( m , n , length ) => {
        let arr = [];
        let a = m > n ? m : n;
        let b = a == m ? n : m;
        for (let i = 0; i < length ; i++){
            arr[i] = Math.round(Math.random() * (a - b ) + b);
        }
        return arr;
    },
    /**
     * 两个p互换位置
     * @param p1id
     * @param p2id
     */
    swapp :  ( p_1_id ,p_2_id ) => {
        let p_1 = $('#'+p_1_id);
        let p_2 = $('#'+p_2_id);
        p_1.children().children().css({'border':'2px solid red'});
        p_2.children().children().css({'border':'2px solid red'});
        let t = document.getElementById(p_1_id).innerHTML;
        document.getElementById(p_1_id).innerHTML=document.getElementById( p_2_id ).innerHTML;
        document.getElementById(p_2_id).innerHTML=t;
        p_1.children().children().css({'border':'none'});
        p_2.children().children().css({'border':'none'});
    },


};

/**
 * 排序类
 * @type {{}}
 */
let sorts = {
    /**
     * 冒泡排序
     * @param data 要排序的数组
     * @param bool true 升序,false 降序
     * @param callback 回调函数
     * @returns {*} array 排序后的数组
     */
    bubbleSort : ( data , bool , callback ) => {
        let length = data.length;
        for (  let i = 0 ; i < length ; i++ ){
            for ( let j = 0 ; j < length - i - 1 ; j++ ){
                let flag = bool ? data[ j ] > data[ j + 1 ] : data[ j ] < data[ j + 1 ] ;
                if ( flag ){
                    let temp = data[ j ];
                    data[ j ] = data [ j + 1 ] ;
                    data [ j + 1] = temp;
                    if( typeof callback === 'function' ){
                        callback( j , j + 1 , 'p' );
                    }
                }
            }
        }
        return data;
    },

    /**
     * 选择排序
     * @param data 要排序的数组
     * @param bool bool true 升序,false 降序
     * @param callback 回调函数
     * @returns {*} array 排序后的数组
     */
    selectionSort : ( data , bool , callback ) => {
        let length = data.length;
        for ( let i = 0 ; i < length ; i++ ){
            for ( let j = i + 1 ; j < length ; j++ ){
                let flag = bool ? data[ i ] > data[ j ] : data[ i ] < data[ j ] ;
                if ( flag ){
                    let temp = data[ i ];
                    data [ i ] = data [ j ];
                    data [ j ] = temp;
                    if( typeof callback === 'function' ){
                        callback( i , j , 'p_' );
                    }
                }
            }
        }
        return data;
    }
};

/**
 * 供排序使用的回调函数
 * @param i
 * @param j
 * @param name
 */
let sortCallback = (i , j , name) => {
    let p_1 = name + '_' + i;
    let p_2 = name + '_' + j;
    commonFun[ 'swapp' ]( p_1 , p_2 );
};

sort.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
    <!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js" ></script>-->
    <script src="//cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" ></script>
    <script src="common.js"></script>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<p id="template" class="progress">
    <p class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width:40%">
        40
    </p>
</p>

</body>
</html>
<style>
    .progress{
        margin-bottom: 10px;
    }

    .progress-bar{
        float: none;
    }
    #template{
        display: none;
    }
</style>
<script>
    $().ready( () => {
        let template = document.getElementById('template').innerHTML;
        /**
         * 初始化条形图
         * @param data
         */
        let init_bar_chart = ( data ) => {
            data.forEach( (element, index)=>{
                let p = document.createElement('p');
                p.innerHTML = '<p>' + template + '</p>';
                p.id = 'p_' + index;
                p.firstElementChild.className = 'progress';
                p.firstElementChild.style = 'width:' + element*2 + '%;';
                p.firstElementChild.firstElementChild.innerHTML = element;
                document.body.appendChild(p);
            });
        };
        let data = commonFun['randonm'](10,50,10);          //生成10位随机数
        init_bar_chart(data);                               //初始化条形图
        sorts['bubbleSort'](data,true,sortCallback);        //排序
    } );
</script>

现在想把swapp方法中互换p的操作

        let t = document.getElementById(p_1_id).innerHTML;
        document.getElementById(p_1_id).innerHTML=document.getElementById( p_2_id ).innerHTML;
        document.getElementById(p_2_id).innerHTML=t;

给延时一秒执行setTimeout似乎没生效。

巴扎黑
巴扎黑

répondre à tous(2)
Ty80
let count = 0;
let sortCallback = (i , j , name) => {
    let p_1 = name + '_' + i;
    let p_2 = name + '_' + j;
    setTimeout(()=> {
      commonFun[ 'swapp' ]( p_1 , p_2 );
    }, ++count * 1000);
};
黄舟

setTimeout 是个异步过程,如果想通过 setTimeout 来实现延时,需要写一大堆回调,而且 for 循环也需要改成回调的方式(或者 generator,逻辑会更复杂)。

我比较懒,所以直接用了 es2017 的 async/await 语法来改写。不过支持这个语法的浏览器还不多,所以又使用 TypeScript 来转译了一下这个代码

改写的代码如下(只贴了几个部分代码):

swapp: async (p_1_id, p_2_id) => {
    let p_1 = $("#" + p_1_id);
    let p_2 = $("#" + p_2_id);
    p_1.children().children().css({ "border": "2px solid red" });
    p_2.children().children().css({ "border": "2px solid red" });

    return new Promise(resolve => {
        setTimeout(function() {
            let t = document.getElementById(p_1_id).innerHTML;
            document.getElementById(p_1_id).innerHTML = document.getElementById(p_2_id).innerHTML;
            document.getElementById(p_2_id).innerHTML = t;
            p_1.children().children().css({ "border": "none" });
            p_2.children().children().css({ "border": "none" });
            resolve();
        }, 400);
    });
}
bubbleSort: async (data, bool, callback) => {
    let length = data.length;
    for (let i = 0; i < length; i++) {
        for (let j = 0; j < length - i - 1; j++) {
            let flag = bool ? data[j] > data[j + 1] : data[j] < data[j + 1];
            if (flag) {
                let temp = data[j];
                data[j] = data[j + 1];
                data[j + 1] = temp;
                await callback(j, j + 1, "p");
            }
        }
    }
    return data;
}
let sortCallback = async (i, j, name) => {
    let p_1 = name + "_" + i;
    let p_2 = name + "_" + j;
    await commonFun["swapp"](p_1, p_2);
};

转义后的代码在 jsfiddle 上看得到——效果是有了,但是距你给的那个动画,还是有差距

https://jsfiddle.net/48dktxnq/

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal