简单 jquery 延迟队列
Simple jquery deferred queue
我有一个方法 foo(param) 是同步的。
我希望可以自由调用 foo(param) 而不执行实际的 foo() 调用,直到稍后发生特定事件。
它看起来很适合延迟/承诺,但我一定是做错了什么,因为超时没有任何效果。
日志方法return应该承诺吗?
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>
是的,你说 q.then(log("..."))
的台词应该说 q.then(function() { log("...") })
。
您的 log
函数没问题,但您的代码当前的工作方式是您 已经调用它 并将其 return 值传递给 then
函数。这就是为什么您需要创建一个新函数,延迟将在稍后解析时调用该函数。
当您执行 q.then(log("1"));
时,它试图获取“log("1")
”的函数值以传递给 then 函数。这是评估功能,这就是为什么您在控制台中看到它们而不是您想要的原因。
像这样包装它们应该可以解决您的问题:
q.then(function() {
log("1")
});
你应该写什么完全取决于"until a particular event later"的意思。
可以有两种解释。
用户事件: 用户事件(在浏览器中)类似于 'click' 或 'mouseover'。它的出现 不是 由 javascript/jQuery 中的任何内容决定的,它可能永远不会发生。但是,通过附加事件处理程序,您可以确保 if/when 事件确实发生,并采取预先确定的行动方案。
日志序列将建立如下:
$(selector).on('eventType', function() {
log("1");
log("2");
log("3");
log("4");
log("5");
log("6");
log("7");
});
异步响应:异步响应是在异步进程完成时发生的事件。它的发生取决于 (a) 正在启动的 aync 进程和 (b) 它的最终完成。同样,完成可能永远不会发生,但比用户事件更有保证。一个写得很好的 aync 进程应该保证完成(成功或不成功)。
日志序列将建立如下:
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()
return 承诺 :
- 已经解决
- 在未来的某个时候解决,
.then()
链中指定的函数将执行,并且 1,2,3,4,5,6,7 将出现在您的日志中。
在最简单的形式中,asyncProcess
可能如下所示:
function asyncProcess() {
return $.when(); //return a resolved promise
}
为了稍微冒险一点,并为承诺链提供一些用途,您可以探索其传输数据的能力。
首先,将 asyncProcess()
改编为 return 一个通过作为参数传递给函数的数字解决的承诺:
function asyncProcess(n) {
return $.when(n);//return a promise resolved with the valie 1
}
然后,修改log()
接受一个数字n
,记录它,然后return 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
每次调用中的参数由上一次调用的 return 值提供。
我有一个方法 foo(param) 是同步的。
我希望可以自由调用 foo(param) 而不执行实际的 foo() 调用,直到稍后发生特定事件。
它看起来很适合延迟/承诺,但我一定是做错了什么,因为超时没有任何效果。
日志方法return应该承诺吗?
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>
是的,你说 q.then(log("..."))
的台词应该说 q.then(function() { log("...") })
。
您的 log
函数没问题,但您的代码当前的工作方式是您 已经调用它 并将其 return 值传递给 then
函数。这就是为什么您需要创建一个新函数,延迟将在稍后解析时调用该函数。
当您执行 q.then(log("1"));
时,它试图获取“log("1")
”的函数值以传递给 then 函数。这是评估功能,这就是为什么您在控制台中看到它们而不是您想要的原因。
像这样包装它们应该可以解决您的问题:
q.then(function() {
log("1")
});
你应该写什么完全取决于"until a particular event later"的意思。
可以有两种解释。
用户事件: 用户事件(在浏览器中)类似于 'click' 或 'mouseover'。它的出现 不是 由 javascript/jQuery 中的任何内容决定的,它可能永远不会发生。但是,通过附加事件处理程序,您可以确保 if/when 事件确实发生,并采取预先确定的行动方案。
日志序列将建立如下:
$(selector).on('eventType', function() {
log("1");
log("2");
log("3");
log("4");
log("5");
log("6");
log("7");
});
异步响应:异步响应是在异步进程完成时发生的事件。它的发生取决于 (a) 正在启动的 aync 进程和 (b) 它的最终完成。同样,完成可能永远不会发生,但比用户事件更有保证。一个写得很好的 aync 进程应该保证完成(成功或不成功)。
日志序列将建立如下:
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()
return 承诺 :
- 已经解决
- 在未来的某个时候解决,
.then()
链中指定的函数将执行,并且 1,2,3,4,5,6,7 将出现在您的日志中。
在最简单的形式中,asyncProcess
可能如下所示:
function asyncProcess() {
return $.when(); //return a resolved promise
}
为了稍微冒险一点,并为承诺链提供一些用途,您可以探索其传输数据的能力。
首先,将 asyncProcess()
改编为 return 一个通过作为参数传递给函数的数字解决的承诺:
function asyncProcess(n) {
return $.when(n);//return a promise resolved with the valie 1
}
然后,修改log()
接受一个数字n
,记录它,然后return 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
每次调用中的参数由上一次调用的 return 值提供。