我有一个同步的方法 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>
答案 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 强>