admin管理员组文章数量:1336320
In JavaScript, we fire functions in quasi-parallel:
window.onload=function(){
document.getElementById("test").addEventListener('click', function1(), false);
//consider it takes 3 seconds to be pleted
document.getElementById("test").addEventListener('click', function2(), false);
}
How we can fire function2()
when the function1()
has been pletely executed?
In jQuery, we can chain a series of functions as (for example):
$(this).fadeIn(3000).fadeOut(2000);
How to make this change of functions in pure JavaScript?
EDIT: In response to a negative ment and vote, I provide this example:
function delay(time, func){
setTimeout(func,time);
}
delay(2000,function(){alert('Function 1');});
delay(1000,function(){alert('Function 2');});
In this example, you'll first see the alert for "Function 2".
In JavaScript, we fire functions in quasi-parallel:
window.onload=function(){
document.getElementById("test").addEventListener('click', function1(), false);
//consider it takes 3 seconds to be pleted
document.getElementById("test").addEventListener('click', function2(), false);
}
How we can fire function2()
when the function1()
has been pletely executed?
In jQuery, we can chain a series of functions as (for example):
$(this).fadeIn(3000).fadeOut(2000);
How to make this change of functions in pure JavaScript?
EDIT: In response to a negative ment and vote, I provide this example:
function delay(time, func){
setTimeout(func,time);
}
delay(2000,function(){alert('Function 1');});
delay(1000,function(){alert('Function 2');});
In this example, you'll first see the alert for "Function 2".
Share Improve this question edited Apr 24, 2023 at 16:17 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Jun 30, 2012 at 8:39 GooglebotGooglebot 15.7k45 gold badges144 silver badges247 bronze badges 7-
1
In your snippet,
function2
is executed afterfunction1
's execution has ended. What's your point? – MaxArt Commented Jun 30, 2012 at 8:40 - @MaxArt no it does not. see the edit! – Googlebot Commented Jun 30, 2012 at 8:44
-
3
Why are you making a delay function that just calls
setTimeout
with the parameters reversed..? O_o if you don't want function 2 to execute before function 1, don't set a timeout less than that of function 1. Normally (your first code block) functions execute one after another. – sachleen Commented Jun 30, 2012 at 8:48 - @sachleen This is just a simple example to show the issue. Consider the functions are fading in/out as given in the jQuery example. – Googlebot Commented Jun 30, 2012 at 8:51
-
1
@Ali Yes, it does.
function1
is pleted and thenfunction2
is executed. What's executed afterfunction2
, is an anonymous function defined infunction1
that is executed asynchronously. If you don't understand this, you lack some basic concepts of Javascript. – MaxArt Commented Jun 30, 2012 at 8:52
6 Answers
Reset to default 4If function1
is asynchronous you will have to modify it so that the caller could pass a callback that will be executed once it pletes, the same way for example jQuery's ajax method provides callbacks such as success, error, ...:
window.onload = function() {
function1(function() {
// the callback is executed once function1 pletes so
// we can now invoke function 2
function2();
});
};
which by the way could be written in a little more concise way as:
window.onload = function() {
function1(function2);
};
I amended the code a bit so it uses JSON and more JQuery-like...
function $c(func){
var obj;
if(func=='alert'){
obj={
'queue':[],
'timeout':null,
'alert':function(timeout,prompt){
obj.queue.push({timeout:timeout,prompt:prompt});
if(obj.timeout==null){
obj.timeout=setTimeout(obj.do_alert,timeout);
}
return obj;
},
'do_alert':function(){
var current=obj.queue.shift();
alert(current.prompt);
if(obj.queue.length>0){
obj.timeout=setTimeout(obj.do_alert,obj.queue[0].timeout);
}else{
obj.timeout=null;
}
},
};
}else if(func=='write'){
obj={
'queue':[],
'timeout':null,
'write':function(timeout,text){
obj.queue.push({timeout:timeout,text:text});
if(obj.timeout==null){
obj.timeout=setTimeout(obj.do_write,timeout);
}
return obj;
},
'do_write':function(){
var current=obj.queue.shift();
var node=document.createTextNode(current.text);
document.body.appendChild(node);
if(obj.queue.length>0){
obj.timeout=setTimeout(obj.do_write,obj.queue[0].timeout);
}else{
obj.timeout=null;
}
},
};
}
return obj;
}
$c('alert').alert(1000,"This is an alert...").alert(3000,"...sequence.");
$c('write').write(1500,"Writing with...").write(1000," delay.").write(1000," Yay!");
Explanation:
This creates a function $c
that returns an object obj
. obj
depends on the passed argument so it contains different methods for use. Separated calls forms different queue so jobs can be done in both style, in sequence or parallel. Calls to the function returns obj
also, so that function calls can be chained together.
If events are synchronous, there is the Continuum
function to run functions in sequence:
function keyedSequence(key, fn) {
fn = fn || this;
key.push({fn:fn});
return function() {
for(var i=0, n, full=1; i<key.length; i++) {
n = key[i];
if(n.fn == fn) {
if(!n.called) n.called = 1, n.args = key.slice.call(arguments);
if(!full) break
}
if(!n.called) full = 0
}
if(full) for(i=0; i<key.length; i++)
n = key[i], key[i] = {fn:n.fn}, n.fn.apply(n, n.args);
}
}
Function.prototype.seq = keyedSequence;
You provide an empty array as the key. Functions keyed with the same key will be grouped together.
window.onload = function() {
var key = [];
document.getElementById("test1").addEventListener('click', function1.seq(key), false);
document.getElementById("test2").addEventListener('click', function2.seq(key), false);
}
Click test2
, then click test1
and order of execution is still function1
then function2
.
Another way of calling it is:
window.onload = function() {
var key = [];
document.getElementById("test1").addEventListener('click', keyedSequence(key, function1), false);
document.getElementById("test2").addEventListener('click', keyedSequence(key, function2), false);
}
There is no way to tell when every event handler set up by a function has been fired without those event handlers being written in such a way to do so explicitly.
If function 1 says "Do something when X is clicked" or "Do something after 20 seconds" or "Do something when an HTTP response is received", and you want function 2 to run after whichever one of those has happened, then you need to set that up in the "something" level, not the "calling function 1" level.
delay(2000,function(){
alert('Function 1');
delay(1000,function(){alert('Function 2');});
});
You can use the self-determined function (or "deferred function determination") like this:
var selfDetermine = function() {
alert("Hi, this is the first time we meet.");
selfDetermine = function() {
alert("Hello again!");
}
}
You can utilize jQuery.when()
to defer the execution of one function until another has pleted it's execution.
Something like this should work for you:
$.when(delay(2000,function(){alert('Function 1');})).done(delay(1000,function(){alert('Function 2');}));
jQuery documentation on when()
本文标签: dom eventsChain of functions in JavaScriptStack Overflow
版权声明:本文标题:dom events - Chain of functions in JavaScript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742334521a2455358.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论