jquery 转换承诺级联

jquery convert promise cascade

我对 jquery promise 级联有疑问,我想简化它。我有一个正在工作的级联函数 (func1)。我在执行下一个函数之前设置了 2 秒超时。我想复制并将其转换为数组缩减形式 (func2),但它不像 func1 那样工作(超时不同)。这是代码:

var Makes=[1,2,3,5,8];
$(document).ready(function(){
    //func1(); //WORKS
    func2();   //NOT WORKS LIKE func1

});

function func1(){
    timeout().then(function(){
       console.log("1");
       return timeout();
    }).then(function(){
       console.log("2");
       return timeout();
    }).then(function(){
       console.log("3");
       return timeout();
    }).then(function(){
       console.log("4");
       return timeout();
    }).then(function(){
       console.log("5");
       return timeout();
    });
}

function func2(){
    /*Makes.reduce(function(Models,Idx){
        return timeout().then(function(){
            console.log(Idx);
            return timeout();
            //return $.when(timeout());
        });
    },0);*/
    Makes.reduce(function(Models,Idx){
        return Models.then(function(){
            return timeout().then(function(){
                console.log(Idx);
                return timeout();
                //return $.when(timeout());
            });
        });
    },0);
}

function timeout(){
    var d = $.Deferred();
    setTimeout(function(){ 
        console.log("wait for 2 sec!");
        d.resolve(); 
    },2000);
    return d.promise();
}

你不应该 return timeout().thenreduce 回调中,而是建立在你从上一次迭代中得到的承诺上:Models.then。你应该给出一个初始承诺,一个立即解决的承诺 ($.when()):

function func2(){
    Makes.reduce(function(Models, Idx) {
        return Models.then(function () {
            return timeout().then(function () {
                console.log(Idx);
            });
        });
    }, $.when()); // resolved starter promise
}

var Makes=[1,2,3,5,8];
$(document).ready(function(){
    func2(); 
});

function func2(){
    Makes.reduce(function(Models, Idx) {
        return Models.then(function () {
            return timeout().then(function () {
                console.log(Idx);
            });
        });
    }, $.when());
}

function timeout(){
    var d = $.Deferred();
    setTimeout(function(){ 
        console.log("wait for 2 sec!");
        d.resolve(); 
    },2000);
    return d.promise();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

或者,您可以使用 "recursive" 类函数来实现异步循环:

function func2(){
    (function repeat(Idx) {
        if (Idx >= Makes.length) return;
        timeout().then(function () {
            console.log(Makes[Idx]);
            repeat(Idx+1);
        });
    }(0));
}

var Makes=[1,2,3,5,8];
$(document).ready(function(){
    func2(); 
});

function func2(){
    (function repeat(Idx) {
        if (Idx >= Makes.length) return;
        timeout().then(function () {
            console.log(Makes[Idx]);
            repeat(Idx+1);
        });
    }(0));
}

function timeout(){
    var d = $.Deferred();
    setTimeout(function(){ 
        console.log("wait for 2 sec!");
        d.resolve(); 
    },2000);
    return d.promise();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>