简单的jquery延迟队列

时间:2015-02-17 07:25:45

标签: javascript jquery-deferred deferred

我有一个同步的方法 foo(param)

我希望可以随时调用 foo(param)而不执行实际的foo()调用,直到特定事件发生时间。

它似乎是延迟/承诺的好候选人,但我必须做错事,因为超时没有任何影响。

log方法是否应该返回promise?

var log = function(message) {
    $('#log').append('<p>' + message + '</p>');
};

$(function() {
 
    var q = new $.Deferred();
    
    q.then(log("1"));
    q.then(log("2"));
    q.then(log("3"));
    q.then(log("4"));
    q.then(log("5"));
    q.then(log("6"));
    q.then(log("7"));
    
    setTimeout(function(){
        q.resolve();
    }, 10000);
    
    
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="log"></div>

3 个答案:

答案 0 :(得分:5)

是的,说明q.then(log("..."))的行应该说q.then(function() { log("...") })

您的log函数很好,但代码当前的工作方式是您已经已经调用它并将其返回值传递给then函数。这就是为什么你需要创建一个新函数,延迟将在它结算时调用它。

答案 1 :(得分:2)

执行q.then(log("1"));时,它会尝试将“log("1")”的函数值传递给then函数。这是评估函数的原因,这就是你在控制台中看到它们而不是你想要的原因。

如此包装它们,应该解决您的问题:

q.then(function() {
    log("1")
});

答案 2 :(得分:0)

你应该写的究竟完全取决于&#34;在特定事件之后的含义&#34;。

可以用两种方式解释。

用户事件:用户事件(在浏览器中)类似于“点击”。或者鼠标悬停&#39;它的出现不是由javascript / jQuery中的任何东西决定的,它可能永远不会发生。但是,通过附加事件处理程序,您可以确保在事件发生时/当事件发生时,采取预定的行动方案。

日志序列将按如下方式建立:

$(selector).on('eventType', function() {
    log("1");
    log("2");
    log("3");
    log("4");
    log("5");
    log("6");
    log("7");
});

Asycnchronous Response:异步响应是异步进程完成时发生的事件。它的出现由(a)启动的异步过程和(b)最终完成确定。同样,完成可能永远不会发生,但比用户事件更有保证。编写良好的异步过程应保证完成(成功或失败)。

日志序列将按如下方式建立:

asyncProcess().then(function() {
    log("1");
    log("2");
    log("3");
    log("4");
    log("5");
    log("6");
    log("7");
});

正如您所看到的,在两种情况下,log()语句都是简单的连续代码行。

在任何一种情况下建立Promise链都是不必要的,因为log()本身是同步的。但是,如果您想探索Deferreds / Promises的性质,那么异步版本可以写成如下:

asyncProcess()
    .then(log.bind(null, "1"))
    .then(log.bind(null, "2"))
    .then(log.bind(null, "3"))
    .then(log.bind(null, "4"))
    .then(log.bind(null, "5"))
    .then(log.bind(null, "6"))
    .then(log.bind(null, "7"));

// Note that .then() takes functions as arguments so `.bind(...)` is necessary to establish functions with bound-in arguments, without actually executing `log("1"); log("2"); log("3");` etc at the time the .then() chain is established.

只要asyncProcess()返回承诺:

  • 已经解决
  • 将来会在某个时候解决,

.then()链中指定的函数将执行,1,2,3,4,5,6,7将出现在您的日志中。

最简单的形式,asyncProcess可能如下所示:

function asyncProcess() {
    return $.when(); //return a resolved promise
}

<强> DEMO

为了更具冒险精神,并为承诺链提供某些目的,您可以探索其传达数据的能力。

首先,调整asyncProcess()以返回一个使用作为参数传递给函数的数字解析的承诺:

function asyncProcess(n) {
    return $.when(n);//return a promise resolved with the valie 1
}

然后,调整log()以接受数字n,记录并返回n+1

function log(n) {
    $('#log').append('<p>' + n + '</p>');
    return n + 1;
}

并按照以下方式调整承诺链:

asyncProcess(1)
    .then(log)
    .then(log)
    .then(log)
    .then(log)
    .then(log)
    .then(log)
    .then(log);

此处,.bind()的需求消失,因为使用原始log时没有任何限制参数。每个log调用中的参数由前一个调用的返回值提供。

<强> DEMO