关于js中的简单回调写法

最近在做一款html5的游戏。其中用到了不少的js回调方法,这也是一个很好的契机,帮我把一些不是很理解清晰的概念又梳理了一次。

首先说下我对回调的理解。最简单的无非就是在某个函数执行完了之后,在接着去执行另一个函数。

用过jqeury的都知道,在ajax方法中会有一个success的属性,这个属性的功能就是在异步或者同步过程中拿到了目标数据后要执行的方法。这也是使用回调的重要的场景。我们要确定某一个动作已经完全的执行到位了,然后再去执行下一个动作。

举个例子吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var myAlarmClock = {};
var count = 0;

var clock = setInterval(function(){
count++;
console.log(count);
},1000);

myAlarmClock.alarm = function(){
if(count==3){
console.log('时间到了!!!');
}
}

myAlarmClock.alarm();

我们用js来写了一个小小的闹钟。我们在myAlarmClock中来设定闹铃的时间,现在我希望在3秒之后闹钟能够提示我。但是很显然,用上面的代码实现的闹钟并没有实现我们理想中的功能。不过大家应该很容易找到其中的错误,myAlarmClock.alarm()方法的位置不正确。因为在alarm函数执行的时候,count的值还是0,所以他不可能会打印出“时间到了”。

然后我们修改下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var myAlarmClock = {};
var count = 0;

var clock = setInterval(function(){
count++;
console.log(count);
//在这里面加入了对count的判断
if(count==3){
myAlarmClock.alarm();
}

},1000);

myAlarmClock.alarm = function(){
//去掉了对count的判断
console.log('时间到了!!!');
}

那么这算不算一个回调呢?

当然不算。这只是一个普通的函数的调用,还不能构成正真意义上的函数回调。

那我们接下来继续,来实现一个真正的回调。

闹钟响了,代表我们有重要的事情要开始做了。这里我们把重要得事情叫作唱歌,我们来写一个唱歌的方法。

1
2
3
myAlarmClock.sing = function(){
console.log('我在唱歌!!!');
}

方法是写好了,我们接下来要把方法实现加入。比如这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var myAlarmClock = {};
var count = 0;

var clock = setInterval(function(){
count++;
console.log(count);
if(count==3){
myAlarmClock.alarm();
myAlarmClock.sing();//开始唱歌
}

},1000);

myAlarmClock.alarm = function(){
console.log('时间到了!!!');
}

myAlarmClock.sing = function(){
console.log('我在唱歌!!!');
}

那如果我还有一个跳舞的方法,在闹钟响起之后,我不想唱歌,我要跳舞,又该怎么做呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var myAlarmClock = {};
var count = 0;

var clock = setInterval(function(){
count++;
console.log(count);
if(count==3){
myAlarmClock.alarm();
myAlarmClock.dancing();//在这里,我们把唱歌替换成了跳舞
}

},1000);

myAlarmClock.alarm = function(){
console.log('时间到了!!!');
}

myAlarmClock.sing = function(){
console.log('我在唱歌!!!');
}

myAlarmClock.dancing = function(){
console.log("我在跳舞");
}

于是,我们删除了唱歌方法,将其改为了跳舞方法。

但是这样的直接改代码的方式可能不是我们最习惯的方法,能不能在alarm里给个参数,让闹钟响起之后直接做回调呢?

当然可以,我们只要改alarm方法就可以了。

1
2
3
4
myAlarmClock.alarm = function(callback){
console.log('时间到了!!!');
callback();
}

这样,我们把sing和dangcing作为参数传进去就ok啦。

代码是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var myAlarmClock = {};
var count = 0;

var clock = setInterval(function(){
count++;
console.log(count);
if(count==3){
myAlarmClock.alarm(myAlarmClock.sing);//直接将myAlarmClock作为参数放进alarm方法
}

},1000);

myAlarmClock.alarm = function(callback){
console.log('时间到了!!!');
callback();
}

myAlarmClock.sing = function(){
console.log('我在唱歌!!!');
}

myAlarmClock.dancing = function(){
console.log("我在跳舞");
}

这样确实实现了一个基本的回调功能,但是,这还不算最完善的。在alarm中,作为参数的callback你必须要保证其为一个方法才行,不然就没办法执行了,所有这里我们还需要做一个判断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var myAlarmClock = {};
var count = 0;

var clock = setInterval(function(){
count++;
console.log(count);
if(count==3){
myAlarmClock.alarm(myAlarmClock.sing);
}

},1000);

myAlarmClock.alarm = function(callback){
console.log('时间到了!!!');
if (typeof callback == 'function') {//加入了对callback的类型检测,如果是一个方法才会执行接下来的代码
callback();
}else{
console.log(callback+"不是一个方法");
}
}

myAlarmClock.sing = function(){
console.log('我在唱歌!!!');
}

myAlarmClock.dancing = function(){
console.log("我在跳舞");
}

以上只是关于回调的一些最最简单的理解,这里还没有涉及到回调函数的作用域的问题,但是在javascript中,回调是一个不能忽视的重要方法,需要好好研究和掌握。