使用延迟(jquery)从数组顺序执行生成

时间:2017-02-06 16:29:37

标签: javascript jquery promise deferred

使用其他解决方案是否有任何意义可以使这更优雅(jquery很好)?

在我的情况下,重要的是只有先前的终止被触发才会触发相应的执行。

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
item one
item one
item two
item two
item three
item three
item four
item four
item five
item five
Done

假设输出应该是:

String1

1 个答案:

答案 0 :(得分:2)

这是使用reduce的理想候选人。此外,您最初的承诺 - 您希望立即解决 - 可以只是$.when(),并且将成为reduce来电的起始值:

&#13;
&#13;
seqExe(["item one", "item two", "item three", "item four", "item five"])

function seqExe(corpus) {
    return corpus.reduce(function (p, item) {
        return p.then(function () {
            console.log(item + ' pending');
            return foo(item);
        });
    }, $.when())
    .then(function(){
        console.log("Done");
    }, function(){
        console.log("Failed");
    });
}

function foo(item) {
    var defer = new $.Deferred();
    window.setTimeout(
        function() {
            defer.resolve()
            console.log(item + ' resolved');
        }, Math.random() * 2000 + 1000);
    return defer.promise();
}
&#13;
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
&#13;
&#13;
&#13;

请注意,在某些jQuery版本中(我在2.1.1中看到),then回调是同步执行的,这会产生错误的输出顺序。这是在jQuery 3中修复的(我尝试了3.1.1,我也在上面的代码片段中链接过)。

以下是使用原生ES6承诺的方法:

&#13;
&#13;
seqExe(["item one", "item two", "item three", "item four", "item five"])

function seqExe(corpus) {
    return corpus.reduce(function (p, item) {
        return p.then(function () {
            console.log(item + ' pending');
            return foo(item);
        });
    }, Promise.resolve())
    .then(function(){
        console.log("Done");
    }, function(){
        console.log("Failed");
    });
}

function foo(item) {
    return new Promise(function (resolve) {
        window.setTimeout(function() {
            resolve();
            console.debug(item + ' resolved');
        }, Math.random() * 2000 + 1000);
    });
}
&#13;
&#13;
&#13;