1、回调
回调callback一种编程技术,通过将函数A传递给另外一个函数B,由函数B来调用函数A,这样的过程被称为回调。通常来说,函数B是已经存在的,而函数A可以自定义,这样就能够实现业务的多样化。
回调在JavaScript的是非常常见的,例如下面一段代码:
$.ajax({ url: "test.html", context: document.body, success: function(){
$(this).addClass("done");
}});
上述代码将一个function作为参数传递给了ajax函数,这里的function是用户可自定义的处理函数。
2、异步
同步为当过程调用函数B的时候,等函数B执行结束过程才会继续。而异步不会等待函数B的执行。异步的好处在于充分利用了CPU时间,避免函数B阻塞导致整个过程阻塞。JavaScript因其出色的异步操作为文明,以JavaScript为语言的NodeJS技术近年来也蓬勃发展,NodeJS异步特性使得它在单线程情况下就能能够执行多个业务,多个IO请求,单线程的好处在于避免了线程切换的开销。
3、Java的异步回调
Java的过程是阻塞的,因此要实现异步回调,需要多线程的支持。要实现回调,B函数在不知道A函数具体实现的情况下能够调用A函数,这是一种多态,需要接口来实现。下面实现一个简单的Java回调,模拟客户端向服务器发送请求,服务器在收到请求后执行客户端的函数(相当于服务器回过来通知客户端),整个过程异步执行。
3.1 实现回调接口
public interface mycallback {
void onData(Object message);
void onError(Exception e);
}
该回调接口规定了回调函数的基本形式,这里有两个回调函数,onData和onError,分别表示正常处理以及异常处理。
3.2回调接口实现类
public class Client implements mycallback{
int count=0;
@Override
public void onData(Object message) {
count++;
System.out.println("received message:"+message.toString());
}
@Override
public void onError(Exception e) {
System.out.println("error!");
}
public void send(String message){
Thread thread=new Thread(new Server(Client.this,message));
thread.start();
}
}
回调接口实现类分别实现了两个回调函数。这个实现类实际相当于一个容易,包装了两个回调函数。回调要求程序传递函数,但是Java的函数是不能直接当做参数传递的,于是需要封装成一个对象来传递,这里的Client即使封装类。Client类的send方法里开一个新线程运行Server代码,并将Client类实例传递给Server执行,这个过程实现了异步回调。
3.3服务器类
public class Server implements Runnable{
mycallback c;
Object message;
public Server(mycallback cl,Object o){
c=cl;
message=o;
}
@Override
public void run() {
try {
c.onData(message+" after server");
}catch (Exception e){
c.onError(e);
}
}
}
服务器类维护了一个回调接口对象,初始化的时候传入回调类的实现,在run方法中执行回调类的回调函数,实现了业务的回调。
3.4测试
public class Work{
public static void main(String[] args){
Client c1=new Client();
c1.send(null);
System.out.println("do others...");
}
}
执行结果为:
do others...
received message:hello
结果里面可以看到两点:
第一、程序是异步执行的,客户端发送了hello的消息,但是没有等待,立即执行了下一个操作,即输出do others...
第二、该程序实现了回调,服务器端调用了客户端的onData函
同理我们测试一下异常回调。
public class Work{
public static void main(String[] args){
Client c1=new Client();
c1.send(null);
System.out.println("do others...");
}
}
执行结果为:
do others...
error!