回调函数,顾名思义,用于回调的函数。回调函数只是一个功能片段,由用户按照回调函数调用约定来实现的一个函数。回调函数是一个工作流的一部分,由工作流来决定函数的调用(回调)时机。
同步调用
一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用
异步调用
一种类似于消息或者时间的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方。
“你中有我,我中有ta”类型
同步代码如下 手机购买商品正常下单付款后,会反馈给用户一个扣款成功的提醒
1. 回调类
// 回调对象
public class MyCallback {
public void process(String msg) {
System.out.println("回调:" + msg);
}
}
2. 顾客类
// 顾客类
public class SynchronizationUser {
private String name;
private App app;
public SynchronizationUser(String name, App app){
this.name = name;
this.app = app;
}
public void buy(String thing){
System.out.println("用户端:购买" + thing);
app.order(new MyCallback(), thing); //被调用方的接口
System.out.println("用户端:物品购买中,请耐心等待");
}
}
3. 服务类
// 服务类
public class App {
public void order(MyCallback callback , String thing) {
//模拟工作
System.out.println();
try {
System.out.println("服务端:" + thing + "下单中......");
Thread.sleep(5000); //模型下单处理
} catch (InterruptedException e) {
e.printStackTrace();
}
//回调操作,反馈信息
System.out.println();
callback.process("扣款成功");
}
}
4. 测试
public static void main(String[] args) {
App app = new App();
SynchronizationUser mx = new SynchronizationUser("mx", app);
mx.buy("可乐");
}
5. 结果
用户端:购买可乐
服务端:可乐下单中......
回调:扣款成功
用户端:物品购买中,请耐心等待
其实这里可以发现,由于程序是同步运行的,所以用户端:物品购买中,请耐心等待该执行逻辑放在了最后,但实际上是不符合常理的。在用户确认购买后就应该执行,而不是扣完钱还要让用户等待。现采用异步回调修改上述User的代码。
你中有我,我中有ta”类型
异步代码如下(只是修改了客户类)
1. 另启线程的客户类
// 异步处理客户类
public class AsynchronizationUser {
private String name;
private App app;
public AsynchronizationUser(String name, App app){
this.name = name;
this.app = app;
}
public void buy(String thing){
System.out.println("用户端:购买" + thing);
new Thread(new Runnable() {
@Override
public void run() {
app.order(new MyCallback(), thing);
}
}).start();
System.out.println("用户端:物品购买中,请耐心等待");
}
}
2. 测试
public static void main(String[] args) {
App app = new App();
AsynchronizationUser mx = new AsynchronizationUser("mx", app);
mx.buy("可乐");
}
3. 结果
用户端:购买可乐
用户端:物品购买中,请耐心等待
服务端:可乐下单中......
回调:扣款成功
你中有我,我中有你类型
对象A调用对象B同时B对象又在调用A对象;实现一个最常见的功能:文件下载。
在下载的过程中,服务端可以返回给我们一些信息,比如:下载进度、下载状态、查看下载URL等。
1. 客户类
public class Client {
private Server mServer = null;
public Client() {
// TODO Auto-generated constructor stub
}
public void download(String url) {
mServer = new Server(Client.this, url);
mServer.Run();
}
public void startDownload() {
// TODO Auto-generated method stub
System.out.println("startDownload");
}
public void stopDownload() {
// TODO Auto-generated method stub
System.out.println("stopDownload");
}
public void showDownloadURL(String url) {
// TODO Auto-generated method stub
System.out.println("Download URL: " + url);
}
public void showDownloadProgress(int progress) {
// TODO Auto-generated method stub
System.out.println("DownloadProgress: " + progress + "%");
}
}
2. 服务类
public class Server {
private Client client;
private String mDownloadUrl = null;
private Timer mTimer = null;
private int mProgress = 0;
public Server(Client client, String url) {
this.client = client;
this.mDownloadUrl = url;
mProgress = 0;
}
public void Run() {
client.showDownloadURL(mDownloadUrl); // 回调下载URL
client.startDownload(); // 回调开始下载
mTimer = new Timer();
mTimer.schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
client.showDownloadProgress(mProgress); // 回调下载进度
if (mProgress == 100) { // 下载进度至100%
client.stopDownload(); // 回调下载结束
mTimer.cancel();
}
mProgress += 10;
}
}, 0, 1000);
}
}
3. 测试
public static void main(String[] args) {
// TODO Auto-generated method stub
Client client = new Client();
client.download( "https://www.baidu.com");
}
4. 结果
Download URL: https://www.baidu.com
startDownload
DownloadProgress: 0%
DownloadProgress: 10%
DownloadProgress: 20%
DownloadProgress: 30%
DownloadProgress: 40%
DownloadProgress: 50%
DownloadProgress: 60%
DownloadProgress: 70%
DownloadProgress: 80%
DownloadProgress: 90%
DownloadProgress: 100%
stopDownload