JS延迟执行

来源:互联网 发布:淘宝店铺纠纷率 编辑:程序博客网 时间:2024/04/20 07:20

 昨晚在写点JS的时候,突然遇到了一个很奇怪的问题,调来调去都没办法解决,然后在微博上请教了一些大神,很快就解决了,然后今早又有人问了我类似的问题,现在基本解决了!

今日我们来说下JS延迟的问题,我先来说下我的问题:

        console.log("1");
        setTimeout(function(){},5000);
        console.log("2");

我本来想打印“1”,隔5秒后再打印2,当然有种很简单的方法:

        console.log("1");
       setTimeout(function(){console.log("2");},5000);      绝对是没问题的。可是我想研究下其中的原理。

 因为setTimeout在JS中是异步执行了,到了时间点就会回调函数,所以它(例子1)根本不会等待5秒在打印“2”的。那么,如何解决好了,网友大神提供了3仲方法:

        1:很多人使用老赵(一个很牛的大神,呵呵,只有一面之缘)的wind.js,我个人并没有去探讨

        2:因为JS是单线程的,可以利用空循环来阻塞线程,阻塞线程的原理我稍后会解析,不过不推荐使用这种方法,毕竟效率太差了,我的CPU顿时彪了一下,先看代码:

(function(dur){var startTime = new Date();while (new Date() - startTime < dur);})(5000);

3:自己封装个Function.prototype.delay,其实也不难,个人感觉这种方法比较好,其实他就是内部封装了setTimeout的方法,我在网上找了代码:

window.onload = function(){
var xx1=new xx("levin"); 
var t=xx1.hi.delay(xx1,3000,"cocoa","yoyo");
xx1.hi("guluglu","jigujigu");
}
var xx=function(n){ 
this.name=n; 
}; 
xx.prototype.hi=function(a,b){ 
console.log(this.name+"-"+a+"-"+b); 
}; 
Function.prototype.delay = function(this1, timeout) {
    this1 = this1 || null;
    timeout = timeout || 0;
    var _this = this;
    var args = [];
    //获取参数,注:第1、第2个参数是保留参数 
    switch (arguments.length) {
    case 1:
        timeout = parseInt(arguments[0]);
        timeout = isNaN(timeout) ? 0 : timeout;
        timeout = timeout < 0 ? 0 : timeout;
        break;
    default:
        for (var i = 0; i < arguments.length; i++) {
            if (i > 1) {
                args.push(arguments[i]);
            };
        };
        break;
    };
    var proxy = function() {
        _this.apply(this1, args);
    };
    return window.setTimeout(proxy, timeout);
};

好了,解决方法说完了,那么我来说下为什么会这样啦。大家都知道JS是单线程的,每个命令来到都进入队列的等待的。那么我再举MISS张若君师姐问我的例子:

代码
setTimeout(function(){console.log("0")},0);
console.log("1");
setTimeout(function(){console.log("2")},3000);
setTimeout(function(){console.log("3")},1000);
setInterval(function(){console.log("4")},2000);
console.log("5");
输出 :1 5 0 3 4 2 4
大家可能会觉得很奇怪,我刚刚明明说每个命令进入队列等待,那么setTimeout(function(){console.log("0")},0);这条语句不是应该先入队列的么?

非也,先给大家看看一张图片


其实这张图片能够很好地解析一切,假如是函数里面的命令,click命令跟(timer)setTimeout的命令同时到达,进队列的顺序按上图一样,那么就能够很好地解析那个例子了,而且也能够解析我昨天的疑惑。

相信大家都有所了解了!呵呵!

关于JS线程我只说了一些皮毛,毕竟我也很水,是随便跟大家分享一下自己总结的经验而已,其实JS还有很多“假象”的。例如ajax异步其实不是真的异步等等,等我深究一下再跟大家一起分享,呵呵!

假如小弟我有什么理解错误的,请各位大神提点提点!


原创粉丝点击