Javascript 我应该如何调用3个函数以逐个执行它们?
如果我需要一个接一个地调用这个函数Javascript 我应该如何调用3个函数以逐个执行它们?,javascript,asynchronous,callback,closures,Javascript,Asynchronous,Callback,Closures,如果我需要一个接一个地调用这个函数 $('#art1').animate({'width':'1000px'},1000); $('#art2').animate({'width':'1000px'},1000); $('#art3').animate({'width':'1000px'},1000); 我知道,在jQuery中,我可以执行以下操作: $('#art1').animate({'width':'1000px'},1000,'line
$('#art1').animate({'width':'1000px'},1000);
$('#art2').animate({'width':'1000px'},1000);
$('#art3').animate({'width':'1000px'},1000);
我知道,在jQuery中,我可以执行以下操作:
$('#art1').animate({'width':'1000px'},1000,'linear',function(){
$('#art2').animate({'width':'1000px'},1000,'linear',function(){
$('#art3').animate({'width':'1000px'},1000);
});
});
async.waterfall([
// A list of functions
function(callback){
// Function no. 1 in sequence
callback(null, arg);
},
function(arg, callback){
// Function no. 2 in sequence
callback(null);
}
],
function(err, results){
// Optional final callback will get results for all prior functions
});
但是,假设我没有使用jQuery,我想调用:
some_3secs_function(some_value);
some_5secs_function(some_value);
some_8secs_function(some_value);
我应该如何调用这个函数来执行一些3secs\u函数
,然后在调用结束后,执行一些5secs\u函数
,然后在调用结束后,调用一些8secs\u函数
更新:
这仍然不起作用:
(function(callback){
$('#art1').animate({'width':'1000px'},1000);
callback();
})((function(callback2){
$('#art2').animate({'width':'1000px'},1000);
callback2();
})(function(){
$('#art3').animate({'width':'1000px'},1000);
}));
三个动画同时开始
我的错误在哪里?因为您用javascript标记了它,所以我会使用计时器控件,因为您的函数名是3、5和8秒。因此,启动计时器,3秒后,第一次呼叫,5秒后第二次呼叫,8秒后第三次呼叫,完成后,停止计时器 通常在Javascript中,您所拥有的功能是正确的,因为函数正在一个接一个地运行,但由于看起来您正在尝试进行定时动画,因此计时器将是您的最佳选择。在Javascript中,有同步和异步函数 同步函数 Javascript中的大多数函数都是同步的。如果要连续调用多个同步函数
doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
他们将按顺序执行<代码>doSomethingElse在doSomething
完成之前不会启动dosomethingusselfe这一次
,在doSomethingElse
完成之前不会启动
异步函数
然而,异步函数不会互相等待。让我们看看上面的代码示例,这次假设函数是异步的
doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
这些函数将按顺序初始化,但它们将大致同时执行。你无法始终如一地预测哪一个将首先完成:恰好花费最短时间执行的一个将首先完成
但有时,您希望异步函数按顺序执行,有时您希望同步函数异步执行。幸运的是,这在回调和超时时都是可能的
回调
假设我们有三个异步函数要按顺序执行,一些3secs函数
,一些5secs函数
,以及一些8secs函数
由于函数可以在Javascript中作为参数传递,因此可以将函数作为回调传递,以便在函数完成后执行
如果我们创建这样的函数
function some_3secs_function(value, callback){
//do stuff
callback();
}
然后您可以按顺序调用,如下所示:
some_3secs_function(some_value, function() {
some_5secs_function(other_value, function() {
some_8secs_function(third_value, function() {
//All three functions have completed, in order.
});
});
});
超时
在Javascript中,您可以告诉函数在特定超时后执行(以毫秒为单位)。这实际上可以使同步函数异步运行
如果我们有三个同步函数,我们可以使用setTimeout
函数异步执行它们
setTimeout(doSomething, 10);
setTimeout(doSomethingElse, 10);
setTimeout(doSomethingUsefulThisTime, 10);
然而,这有点丑陋,违反了法律。我们可以通过创建一个接受函数数组和超时的函数来解决这个问题
function executeAsynchronously(functions, timeout) {
for(var i = 0; i < functions.length; i++) {
setTimeout(functions[i], timeout);
}
}
总之,如果您有要同步执行的异步函数,请使用回调;如果您有要异步执行的同步函数,请使用超时。您的函数应该使用回调函数,该函数在完成时会被调用
function fone(callback){
...do something...
callback.apply(this,[]);
}
function ftwo(callback){
...do something...
callback.apply(this,[]);
}
然后,用法如下所示:
fone(function(){
ftwo(function(){
..ftwo done...
})
});
我不会在这里深入讨论setTimeout,但是:
- 在本例中,我添加了要作为字符串执行的代码。这是将var传递给setTimeout函数的最简单方法,但纯粹主义者会抱怨
- 也可以传递不带引号的函数名,但不能传递任何变量
- 您的代码不会等待setTimeout触发李>
- 一开始你很难理解这个问题:因为上一点,如果你从调用函数传递了一个变量,那么在超时触发时,这个变量就不再存在了——调用函数已经执行了,变量也消失了
- 大家都知道我使用匿名函数来解决这些问题,但是有更好的方法
some_3secs_function(some_value, function() {
some_5secs_function(other_value, function() {
some_8secs_function(third_value, function() {
//All three functions have completed, in order.
});
});
});
setTimeout
setTimeout
的回调animate
函数实际上并不需要3秒钟。通过延迟和回调来模拟这种影响
您需要的是一个队列。在内部,jQuery对动画进行排队,仅在相应动画完成后执行回调。如果回调随后启动另一个动画,效果是它们按顺序执行
在最简单的情况下,这相当于以下内容:
window.setTimeout(function() {
alert("!");
// set another timeout once the first completes
window.setTimeout(function() {
alert("!!");
}, 1000);
}, 3000); // longer, but first
这是一个通用的异步循环函数。它将按顺序调用给定的函数,在每个函数之间等待指定的秒数
function loop() {
var args = arguments;
if (args.length <= 0)
return;
(function chain(i) {
if (i >= args.length || typeof args[i] !== 'function')
return;
window.setTimeout(function() {
args[i]();
chain(i + 1);
}, 2000);
})(0);
}
显然,您可以修改此选项,以占用可配置的等待时间,或立即执行第一个函数,或在链中的函数返回false
时停止执行,或在指定上下文中应用函数,或使用ECM的JavaScript功能
loop(
function() { alert("sam"); },
function() { alert("sue"); });
Promise.resolve($('#art1').animate({ 'width': '1000px' }, 1000).promise()).then(function(){
return Promise.resolve($('#art2').animate({ 'width': '1000px' }, 1000).promise());
}).then(function(){
return Promise.resolve($('#art3').animate({ 'width': '1000px' }, 1000).promise());
});
new Promise(function(fulfill, reject){
//do something for 5 seconds
fulfill(result);
}).then(function(result){
return new Promise(function(fulfill, reject){
//do something for 5 seconds
fulfill(result);
});
}).then(function(result){
return new Promise(function(fulfill, reject){
//do something for 8 seconds
fulfill(result);
});
}).then(function(result){
//do something with the result
});
async.waterfall([
// A list of functions
function(callback){
// Function no. 1 in sequence
callback(null, arg);
},
function(arg, callback){
// Function no. 2 in sequence
callback(null);
}
],
function(err, results){
// Optional final callback will get results for all prior functions
});
some_3secs_function(this.some_value).then(function(){
some_5secs_function(this.some_other_value).then(function(){
some_8secs_function(this.some_other_other_value);
});
});
one(some_value).then(function(return_of_one){
two(return_of_one).then(function(return_of_two){
three(return_of_two);
});
});
async function run(){
await $('#art1').animate({'width':'1000px'},1000,'linear').promise()
await $('#art2').animate({'width':'1000px'},1000,'linear').promise()
await $('#art3').animate({'width':'1000px'},1000,'linear').promise()
}
/*
funcCond : function to call to check whether a condition is true
readyAction : function to call when the condition was true
checkInterval : interval to poll <optional>
timeout : timeout until the setTimeout should stop polling (not 100% accurate. It was accurate enough for my code, but if you need exact milliseconds, please refrain from using Date <optional>
timeoutfunc : function to call on timeout <optional>
*/
function waitUntil(funcCond, readyAction, checkInterval, timeout, timeoutfunc) {
if (checkInterval == null) {
checkInterval = 100; // checkinterval of 100ms by default
}
var start = +new Date(); // use the + to convert it to a number immediatly
if (timeout == null) {
timeout = Number.POSITIVE_INFINITY; // no timeout by default
}
var checkFunc = function() {
var end = +new Date(); // rough timeout estimations by default
if (end-start > timeout) {
if (timeoutfunc){ // if timeout function was defined
timeoutfunc(); // call timeout function
}
} else {
if(funcCond()) { // if condition was met
readyAction(); // perform ready action function
} else {
setTimeout(checkFunc, checkInterval); // else re-iterate
}
}
};
checkFunc(); // start check function initially
};
doSomething();
waitUntil(function() { return doSomething_value===1;}, doSomethingElse);
waitUntil(function() { return doSomethingElse_value===1;}, doSomethingUseful);