回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
我们为什么需要回调机制呢?简单理解,就是 A类的 a() 方法调用 B类 的 b() 方法,但是 b() 方法的执行时间较长,如果同步调用的话,a() 方法要阻塞很长的一段时间。而异步回调就是,A类 提供一个回调函数 f(),然后 a() 方法调用 b() 方法后,立即返回,继续其下面的操作,而 b() 方法在执行完对应的逻辑后,主动调用 A类 的回调函数进行通知,从而实现异步的操作。
同步调用的过程中,a() 方法调用 b() 方法后,需要阻塞,等待 b() 方法执行完返回才继续下面的逻辑。
异步调用的话,a() 方法在调用完 b() 方法后,可以继续执行自己的逻辑。而 b() 方法执行完会主动回调 a() 方法的回调函数进行通知。
场景:老师在课堂上布置了一个作业,然后就下课了,让学生课后做完主动通知老师。
1.实现Teacher类,提供一个问问题的方法以及一个回调方法
2.实现Student类,学生完成作业主动通知老师
import javafx.util.Callback;
/**
* Teacher
*/
public class Teacher implements Callback {
private Student student;
public Teacher(Student student){
this.student = student;
}
public void question(){
System.out.println("布置课后作业");
new Thread(() -> student.answer(this)).start();
System.out.println("下课");
}
@Override
public Object call(Object param) {
System.out.println(param);
return null;
}
}
import java.util.concurrent.TimeUnit;
/**
* Student
*/
public class Student {
public void answer(Callback callback){
try {
TimeUnit.SECONDS.sleep(3);
callback.call("已完成作业");
}catch (Exception e){
e.printStackTrace();
}
}
}
/**
* 测试类
*/
public class Test {
public static void main(String[] args) {
new Teacher(new Student()).question();
}
}
运行结果
上面提到的异步回调是针对同一个系统,不同类之间的回调方式。但是,有些时候,我们需要对两个不同的系统进行异步回调的通知,这该如何实现呢?
之前有对接过微信支付的功能,商家系统这边下单后,会生成订单,然后需要向微信那边提供一个支付结果回调的 url,这个 url 必须是可以直接请求返回结果的。其实原理跟上面的 demo 类似,只不过是回调函数换成 http 接口的形式而已。