jquery $when 多个异步怎么变同步?

想多个异步定时任务,一个接一个触发,不是同时触发

            var task1 = function(){
                var $d = $.Deferred();
                setTimeout(function(){
                    console.log('t1');
                    $d.resolve();
                },1000);
                return $d.promise();
            }

            //2
            var task2 = function(){
                var $d = $.Deferred();
                setTimeout(function(){
                    console.log('t2');
                    $d.resolve();
                },1200);
                return $d.promise();
            }

            //3
            var task3 = function(){
                var $d = $.Deferred();
                setTimeout(function(){
                    console.log('t3');
                    $d.resolve();
                },1200);
                return $d.promise();
            }

            //4
            var task4 = function(){
                var $d = $.Deferred();
                setTimeout(function(){
                    console.log('t4');
                    $d.resolve();
                },1200);
                return $d.promise();
            }
      
            $.when(task1(),task2(),task3(),task4()).done(function(){
                console.log('done');
            });

代码没有按预期的结果:t1,等待1秒后出现t2,后面的跟前面一样
但现实是同时触发出现了,不知道是不是哪里写错了...求指导,谢谢!
在线代码例子:可以运行看看效果
http://jsfiddle.net/Lq48vy7m/

如果是用then好像也不行,结果会更奇怪

  
 var task1 = function(){
                var $d = $.Deferred();
                setTimeout(function(){
                    console.log('t1');
                    $d.resolve();
                },1000);
                return $d.promise();
            }

            //2
            var task2 = function(){
                var $d = $.Deferred();
                setTimeout(function(){
                    console.log('t2');
                    $d.resolve();
                },1200);
                return $d.promise();
            }

            //3
            var task3 = function(){
                var $d = $.Deferred();
                setTimeout(function(){
                    console.log('t3');
                    $d.resolve();
                },1200);
                return $d.promise();
            }

            //4
            var task4 = function(){
                var $d = $.Deferred();
                setTimeout(function(){
                    console.log('t4');
                    $d.resolve();
                },1200);
                return $d.promise();
            }
      
task1().then(task2()).then(task3()).then(task4()).then(function(){
                console.log('ok');
            })
      
  

输出结果居然是

t1
ok
t2
t3
t4

在线地址:http://jsfiddle.net/rbtnmz2e/
改回这样就可以了

task1().then(function(){
                return task2()
            }).then(function(){
                return task3()
            }).then(function(){
                return task4()
            }).then(function(){
                console.log('ok');
            })

另外用那些比较好的异步库,如:when.js 那个?

//根据最佳奖答案写一个promise版本,方便大家使用
var tasks = [
    function() {
        return new Promise(function(resolve, reject) {
          setTimeout(resolve, 100, '1');
          console.log('1')
        });
    },
    function() {
        return new Promise(function(resolve, reject) {
          setTimeout(resolve, 100, '2')
          console.log('2')
        })
    },
    function() {
        return new Promise(function(resolve, reject) {
          setTimeout(resolve, 100, '3')
          console.log('3')
        });
    },
    function() {
        return new Promise(function(resolve, reject) {
          setTimeout(resolve, 100, '4')
          console.log('4')
        });
    },
];

tasks.reduce((previous, p) => previous.then(p), Promise.resolve());

在线:http://jsfiddle.net/yyman001/...

//promise 第二版
//根据最佳奖答案写一个promise版本,方便大家使用

let p1 = new Promise(function(resolve, reject) {
          setTimeout(resolve, 100, '1');
          console.log('1')
        });
let p2 = new Promise(function(resolve, reject) {
          setTimeout(resolve, 100, '2')
          console.log('2')
        })
let p3 = new Promise(function(resolve, reject) {
          setTimeout(resolve, 100, '3')
          console.log('3')
        });
let p4 = new Promise(function(resolve, reject) {
          setTimeout(resolve, 100, '4')
          console.log('4')
        });
Promise.all([p1, p2, p3]).then(function(values) {
  console.log('values',values);
});

http://jsfiddle.net/yyman001/...

阅读 8.7k
3 个回答

同时触发是正常的,因为你就是那样写的,看这里:

$.when(task1(),task2(),task3(),task4())

虽然用了when,但你确实是同时执行了task1()task2()task3()task4()这四个函数,所以四个异步操作真心是同时触发的,没毛病!

补充:

如果你希望顺序执行上面4个异步任务,用下面这种方式:

var tasks = [
    function() {
        var $d = $.Deferred();
        setTimeout(function() {
            console.log('t1');
            $d.resolve();
        }, 1000);
        return $d.promise();
    },
    function() {
        var $d = $.Deferred();
        setTimeout(function() {
            console.log('t2');
            $d.resolve();
        }, 1200);
        return $d.promise();
    },
    function() {
        var $d = $.Deferred();
        setTimeout(function() {
            console.log('t3');
            $d.resolve();
        }, 1200);
        return $d.promise();
    },
    function() {
        var $d = $.Deferred();
        setTimeout(function() {
            console.log('t4');
            $d.resolve();
        }, 1200);
        return $d.promise();
    }
];

tasks.reduce((previous, p) => previous.then(p), $.Deferred().resolve());

又去看了下promise,恩,好像then方法我测试的时候写写少了return....真是瞎了眼...

task1().then(function(){
                return task2()
            }).then(function(){
                return task3()
            }).then(function(){
                return task4()
            }).then(function(){
                console.log('ok');
            })

不知道它这个在线是不是有问题,我在项目中这么写是没问题的...把自己坑了一把
http://jsfiddle.net/rq80vph0/

也可以这样执行
var task1 = function(){

   setTimeout(function(){
    console.log('t1');
   },1000);

}
//2
var task2 = function(){

 setTimeout(function(){
    console.log('t2');
 },1200);

}
//3
var task3 = function(){

 setTimeout(function(){
    console.log('t3');
 },1200);

}
//4
var task4 = function(){

 setTimeout(function(){
    console.log('t4');
 },1200);

}
//当某一个执行完,在执行
$.when(task1()).done(task2()).done(task3()).done(task4()).done(function(){

console.log("哈哈");

});

推荐问题
宣传栏