比方说,我有两个函数,里面有随机代码,也基于用户的系统(慢,中,或快),没有办法告诉两个函数需要多长时间才能完成,所以使用setTimeout仅在function1完成后尝试触发function2时不实用.
你怎么能使用jQuery.deferred使function2只在function1之后触发,无论时间要求是什么,并且考虑到这两个函数都是100%非jQuery函数,里面没有jQuery代码,因此jQuery完全无法观察到?最重要的是,这些函数可能包括像.css()这样的jQuery方法,这些方法没有时间关联,并且可以在旧计算机上运行得更慢.
如果我这样调用它,我如何确保function2没有与function1同时执行:
function1(); function2();
使用$.deferred?除了那些关于$.deferred之外的任何其他答案也欢迎!
3月20日新增:
如果function1()是一个lambda函数,如果根据用户输入,该函数可能有也可能没有异步调用,并且无法判断该函数将执行多少操作,该怎么办?它是一个函数,你不知道接下来会发生什么,但无论如何,你仍然希望function2只有在完成lambda函数(function1)的所有操作后才能执行,无论如何只要异步方面完成,它就需要很长时间.怎么能实现这一目标?
3月22日新增:
所以我想我要问的唯一方法就是将匿名函数作为回调传递给异步函数,这些函数在完成后执行回调,或者创建事件监听器,在事件最终触发时执行你想要的操作.
实际上没有任何方法可以在两个单独的行上执行异步调用并按顺序触发它们,而无需在包含所述函数的框架内手动构造机制(事件处理程序)来处理其操作的实际执行.
这些类型的机制的一个很好的例子是jQuery的.queue()方法和$.Defferred对象.
下面的答案以及在.queue()和使用$.Deferred上阅读jQuery的API有助于澄清这一点.
Tgr在下面给出了一个很好的例子,说明如何使用jQuery的$.Deferred对象创建自定义可链接函数,而自定义函数本身并不一定要在其中包含任何jQuery代码,这正是我想要的.
function first(deferred) {
// do stuff
deferred.resolve();
}
function second() {
// do stuff
}
$.Deferred(first).then(second);
但正如Tomalak指出的那样,这是不必要的,除非你先做一些非常棘手的事情(比如利用网络工作者).
更新:
基本思想是,无论何时执行非直接的操作,都会创建一个Deferred对象,并返回该对象. (jQuery的AJAX调用已经这样做了.)然后你可以使用Deferred.then来延迟后续操作.
function first() {
var deferred = $.Deferred();
var callback = function() {
deferred.resolve();
}
// do immediate stuff
someAsyncOperation(callback);
return deferred.promise(); // turns the Deferred into a Promise,which
// means that resolve() will not be accessible
}
function second() {
// do stuff
}
first().then(second); // or: $.when(first).then(second)
如果second也是异步操作,则可以使用$.when的合并功能:
function second() {
var anotherDeferred = $.Deferred();
// do stuff with anotherDeferred
return anotherDeferred.promise();
}
$.when(first(),second()).then(third); // third will run at the moment when
// both first and second are done