jquery,如何在另一个函数结束后立即运行一个函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14412026/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jquery, how to run a function as soon as another function ends
提问by nthChild
*Note: Re-writing question:
*注:重写问题:
I am trying to write the following outsideof the individual function calls:
我正在尝试在单个函数调用之外编写以下内容:
example:
例子:
function f1(){ do something 1 } function f2(){ do something 2 } run function 1 when done run function 2
(See comments below for jsfiddles)
(有关 jsfiddles,请参阅下面的评论)
Problem is, the boxes load at the same time. Behavior SHOULD be, load red, when done, load green.
问题是,箱子同时加载。行为应该是,加载红色,完成后加载绿色。
If this isn't a common method in jQuery, let me know, maybe I'm just chasing a ghost...
如果这不是 jQuery 中的常用方法,请告诉我,也许我只是在追鬼……
采纳答案by BeardFist
You could simply call the second function at the end of the first.
您可以简单地在第一个函数的末尾调用第二个函数。
$(document).ready(function() {
function firstFunction(){
alert("this is the first function!");
secondFunction();
}
function secondFunction(){
alert("this is the second function!");
}
firstFunction();
});
Alternatively, if you do not wish to call the second function every time you call the first, you could simply call them sequentially
或者,如果您不想每次调用第一个函数时都调用第二个函数,则可以简单地按顺序调用它们
firstFunction();
secondFunction();
This works because it will wait until firstFunction
is done before it moves on to secondFunction
fiddle
这是有效的,因为它会等到firstFunction
完成后再继续secondFunction
摆弄
回答by JR.
Depends on the functions.
取决于功能。
Short answer:
简短的回答:
For synchronousfunctions: Just call them one after the other.
对于同步函数:只需一个接一个地调用它们。
For asynchronousfunctions: Depends on what makes it asynchronous.
对于异步函数:取决于使其异步的原因。
jQuery animations? Define a callback parameter from the animation's method or from the fx queue's Promise object.
jQuery 动画?从动画的方法或 fx 队列的 Promise 对象定义回调参数。
setTimeout/setInterval/something else? Most likely, the functions will need to be rewritten to provide a callback or Deferred/Promise object.
setTimeout/setInterval/其他什么?最有可能的是,需要重写这些函数以提供回调或 Deferred/Promise 对象。
Long answer:
长答案:
According to the jsFiddles in your comments, you've got these two functions:
根据您评论中的 jsFiddles,您有这两个功能:
function firstFunction(){
$(".one").fadeIn(1000).delay(2000).fadeOut();
}
function secondFunction(){
$(".two").fadeIn(1000).delay(2000).fadeOut();
}
You want secondFunction
to run after firstFunction
, and you'd prefer not to tamper with these functions. If that's the case, there's only one solution I can think of: Get a Promise objectfrom the element that firstFunction
is animating, and then define secondFunction
as a success handler:
您想secondFunction
在 之后运行firstFunction
,并且不想篡改这些功能。如果是这种情况,我只能想到一个解决方案:从正在设置动画的元素获取一个Promise 对象firstFunction
,然后定义secondFunction
为成功处理程序:
firstFunction();
$('.one').promise().then(secondFunction);
promise()
returns a Promise object bound to the current animation state of that element. $('.one').promise().then(secondFunction)
is essentially saying "I promise to run secondFunction
when the current animation for .one
is done.
promise()
返回绑定到该元素当前动画状态的 Promise 对象。$('.one').promise().then(secondFunction)
本质上是说“我保证secondFunction
在当前动画.one
完成后运行。
If you're willing to tamper with the existing functions, you could also call secondFunction
as a callback parameter of the fadeOut
within firstFunction
, but that's not a very elegant solution.
如果你愿意与现有的功能,篡改,您还可以拨打secondFunction
作为的回调参数fadeOut
内firstFunction
,但是这不是一个很优雅的解决方案。
If you're willing to rewrite your functions, the ideal solution is to tame your async functions by using Deferreds and Promises. Here's a quick primer:
如果你愿意重写你的函数,理想的解决方案是使用 Deferreds 和 Promises 来驯服你的异步函数。这是一个快速入门:
- In jQuery, a Deferredobject is a special object you can use to define the success/fail state of a function. You use this inside your functions.
- A Promiseobject is a special object that you can use to add callbacks to those success/fail states. You use this outside your functions.
- 在 jQuery 中,Deferred对象是一种特殊的对象,可用于定义函数的成功/失败状态。你在你的函数中使用它。
- 一个承诺对象是一个特殊的对象,你可以用它来添加回调那些成功/失败状态。你在你的函数之外使用它。
Using these tools, you can rewrite your functions to specify when they're "done," and you can give code outside your functions the ability to know when (and execute after) they're done.
使用这些工具,您可以重写您的函数以指定它们何时“完成”,并且您可以让函数外部的代码能够知道它们何时(并在之后执行)它们完成。
Rewritten to use Deferred and Promise, the code looks like this:
重写为使用 Deferred 和 Promise,代码如下所示:
function firstFunction(){
var deferred = $.Deferred();
$(".one").fadeIn(1000).delay(2000).fadeOut(function() {
deferred.resolve();
});
return deferred.promise();
}
function secondFunction(){
var deferred = $.Deferred();
$(".two").fadeIn(1000).delay(2000).fadeOut(function() {
deferred.resolve();
});
return deferred.promise();
}
firstFunction().then(secondFunction);
If all your functions are written this way, you can control their execution order and have them run sequentially using then()
. Here's a more thorough example:
如果您的所有函数都以这种方式编写,您可以控制它们的执行顺序并使用then()
. 这是一个更彻底的例子:
function one(){
var deferred = $.Deferred();
$(".one").fadeOut(500, function() {
$(this).appendTo('body').fadeIn(500, function() { deferred.resolve(); });
});
return deferred.promise();
}
function two(){
var deferred = $.Deferred();
$(".two").fadeOut(1500, function() {
$(this).appendTo('body').fadeIn(500, function() { deferred.resolve(); });
});
return deferred.promise();
}
function three(){
var deferred = $.Deferred();
$(".three").fadeOut(1000, function() {
$(this).appendTo('body').fadeIn(500, function() { deferred.resolve(); });
});
return deferred.promise();
}
function four(){
var deferred = $.Deferred();
$(".four").fadeOut(750, function() {
$(this).appendTo('body').fadeIn(500, function() { deferred.resolve(); });
});
return deferred.promise();
}
function five(){
var deferred = $.Deferred();
$(".five").fadeOut(600, function() {
$(this).appendTo('body').fadeIn(500, function() { deferred.resolve(); });
});
return deferred.promise();
}
one()
.then(two)
.then(three)
.then(four)
.then(five);
回答by frosty
Deferreds are an option. You could always do the following:
延期是一种选择。您始终可以执行以下操作:
$.when(firstFunction()).then(secondFunction);
The only trick is that inside firstFunction, you would need to do the following:
唯一的技巧是在 firstFunction 中,您需要执行以下操作:
function firstFunction(){
var deferred = $.Deffered();
$.get(url,function(r){
deferred.resolve();
});
return deferred;
}
The when function will wait until the deferred returned by the firstFunction call is resolved. Once the deferred is resolved (in the ajax success callback) the '.then' statement will fire, calling your secondFunction.
when 函数将等待,直到 firstFunction 调用返回的延迟被解决。一旦延迟解决(在 ajax 成功回调中)'.then' 语句将触发,调用您的 secondFunction。
The jQuery docs explain the Deferred API very well.
jQuery 文档很好地解释了延迟 API。
回答by Koenyn
you can use the jquery Callbacks function, from v1.7up
您可以使用 jquery 回调函数,从 v1.7up
var callbacks = $.Callbacks();
callbacks.add( firstFunction );
callbacks.add( secondFunction );
callbacks.fire( );
回答by GeorgeVremescu
instead of
代替
firstFunction(function(){
secondFunction();
});
write
写
firstFunction();
secondFunction();
回答by meehocz
I had this problem recently. If you have a bunch of functions that do async stuff, just make them all to return a Deferred, which you manually resolve when the function async job is finished. Then you can put the functions in an array and run them sequentially:
我最近遇到了这个问题。如果您有一堆执行异步操作的函数,只需让它们全部返回一个 Deferred,当函数异步作业完成时您手动解析它。然后你可以把函数放在一个数组中并按顺序运行它们:
// Sample asynchronous function that returns Deferred
var f = function(name){
console.log('Function root start', name);
var d = $.Deferred();
d.done(function(result){
console.log('Async work finish', name, result);
});
setTimeout(function(){
setTimeout(function(){
d.resolve('Hello');
}, 200);
}, 1000);
console.log('Function root finish', name);
return d;
};
// Array with functions
var defs = [];
defs.push(f.bind(null, 1));
defs.push(f.bind(null, 2));
defs.push(f.bind(null, 3));
// Recursive sequential calling
var i = 0;
var runAtIndex = function (i) {
i < defs.length && defs[i]().done(function() { runAtIndex(i + 1); });
}
runAtIndex(i);