天津魔方网站建设,国外jquery特效网站,网站备案帐号密码,会员wordpress主题一、什么是回调#xff1a;
回调是一种双向的调用模式#xff0c;程序模块之间通过这样的接口调用完成通信联系#xff0c;回调的核心就是回调方将本身即this传递给调用方#xff0c;这样调用方就可以在调用完毕之后再告诉回调方它想要知道的信息。 回调函数用于层间协作
回调是一种双向的调用模式程序模块之间通过这样的接口调用完成通信联系回调的核心就是回调方将本身即this传递给调用方这样调用方就可以在调用完毕之后再告诉回调方它想要知道的信息。 回调函数用于层间协作上层将本层函数安装在下层这个函数就是回调而下层在一定条件下触发回调例如作为一个驱动是一个底层他在收到一个数据时除了完成本层的处理工作外还将进行回调它将这个数据交给上层应用层来做进一步处理这在分层的数据通信中很普遍。其实回调和API非常接近他们的共性都是跨层调用的函数。但区别是API是低层提供给高层的调用一般这个函数对高层都是已知的而回调正好相反他是高层提供给底层的调用对于低层他是未知的必须由高层进行安装。这个安装函数其实就是一个低层提供的API安装后低层不知道这个回调的名字但它通过一个函数指针来保存这个回调在需要调用时只需引用这个函数指针和相关的参数指针。
其实回调就是该函数写在高层低层通过一个函数指针保存这个函数在某个事件的触发下低层通过该函数指针调用高层那个函数。从调用方式上看可以分为两类同步回调、异步回调。 通俗来说
就是A类需要调用B类中的方法然后B类方法执行结束后通过函数指针A类传过来调用A类中的回调方法。 回调机制使用场景
在项目中在支付宝的沙箱支付中就用到了回调机制。在支付Controller层中通过pay方法调用支付宝提供的API跳转支付宝支付界面。 但是在支付接口中我们并不是等待支付宝支付页面支付完成才继续走下去即非阻塞式而且我们在pay方法中也并不知道支付宝支付页面中的支付结果具体如何。那么我们该如何获取结果呢就是通过支付宝的异步回调接口来通知我们结果。 在支付完成后支付宝会异步回调Controller层中的回调方法来通知结果。 二、同步回调与异步回调
1、同步回调
同步调用是一种阻塞式调用是最基本并且最简单的一种调用方式类A的方法a()调用类B的方法b()一直等待b()方法执行完毕a()方法才能继续往下走。这种调用方式适用于方法b()执行时间不长的情况因为b()方法执行时间一长或者直接阻塞的话a()方法的余下代码是无法执行下去的这样会造成整个流程的阻塞。 例如上方支付宝回调场景加入是同步机制回调那么在pay方法中我们就需要等待支付宝支付结果那假设网络等因素导致支付结果很慢还没有出来那么我们的程序就一直阻塞在这里那这样性能就会非常糟糕。
2、异步回调
1异步调用是为了解决同步调用可能出现阻塞导致整个流程卡住而产生的一种调用方式。类A的方法方法a()通过新起线程的方式调用类B的方法b()代码接着直接往下执行这样无论方法b()执行时间多久都不会阻塞住方法a()的执行。但是这种方式由于方法a()不等待方法b()的执行完成在方法a()需要方法b()执行结果的情况下必须通过一定的方式对方法b()的执行结果进行监听。为了完成这点就需要另开一个线程了。 2异步调用在应用程序框架中具有广泛的应用并且特指多线程情况下。它同Windows的消息循环机制消息响应消息队列事件驱动机制以及设计模式中的观察者模式等都是紧密相关的。 在单线程方式下计算机是一台严格意义上的冯·诺依曼式机器一段代码调用另一段代码时只能采用同步调用必须等待这段代码执行完返回结果后调用方才能继续往下执行。有了多线程的支持可以采用异步调用调用方和被调方可以属于两个不同的线程调用方启动被调方线程后不等对方返回结果就继续执行后续代码。被调方执行完毕后通过某种手段通知调用方结果已经出来请酌情处理。异步回调常见于请求服务器数据当取到数据时,会进行回调例如支付宝支付回调。 三、异步回调例子JAVA
上面讲了那么多其实所谓回调就是A类中调用了B类的某个方法C然后B类反过来调用A类的方法DD这个方法就叫回调方法。
Class A实现接口CallBack callback——背景1
class A中包含一个class B的引用b ——背景2
class B有一个参数为callback的方法f(CallBack callback) ——背景3
A的对象a调用B的方法 f(CallBack callback) ——A类调用B类的某个方法 C
然后b就可以在f(CallBack callback)方法中调用A的方法 ——B类调用A类的某个方法D
/*** java 异步接口回调*/
public interface CallBack {/*** 这时一个回调接口* param result*/public void resultNotify(String result);
}/** 相当于A类 有任务处理 需要调用B类中的方法进行处理* author cg* version 1.0* Date 2024/4/20 15:33*/
public class Chen implements CallBack{private Li li;public void setLi(Li li){this.lili;}//调用Li类 进行任务处理public void ToTaskLi( String task){//另起线程模拟异步调用场景new Thread(new Runnable() {Overridepublic void run() {li.doTask(Chen.this,task);}}).start();//将任务交由类li处理 Chen类继续往下执行别的任务 无需阻塞playGame();}public void playGame(){System.out.println(Chen玩去了.......);}//异步回调函数Overridepublic void resultNotify(String result) {System.out.println(Chen的接口回调结果result);}
}/** 相等于任务处理类 处理完成后通知A类 并将结果告知* author cg* version 1.0* Date 2024/4/20 15:33*/
public class Li {public void doTask(CallBack callBack,String task){System.out.println(Li接受到任务task);//模拟处理任务for (int i 0; i 100000; i) {}System.out.println(Li类任务处理完毕......);String result任务处理成功;//调用chen类的回调函数callBack.resultNotify(result);}
}/** 测试java异步回调* author cg* version 1.0* Date 2024/4/20 15:43*/
public class TestYiBuHuiDiao {public static void main(String[] args) {Chen chennew Chen();Li li new Li();chen.setLi(li);String task拿取参数任务;chen.ToTaskLi(task);}
}结果 代码解析
在这段代码中Chen类是CallBack接口的实现类而调用Li类的doTask()方法中传递了一个Chen.this参数this关键字的使用Chen.this相当于类Chen的实例对象和Chen chen一样。Li.doTask(CallBack callback)中参数要求是CallBack类型因为Chen类实现了CallBack接口所以它的实例可以作为CallBack类型的参数传递。 为什么使用CallBack callback作为参数
这里就涉及到Java的接口和多态。因为CallBack是一个接口任何实现了该接口的类都必须实现接口中定义的所有方法。所以只需要传入一个CallBack类型的引用就可以而在Li类中不需要关心这个类指向的是哪个类的实例在这里是指向的Chen类实例也可以是各种实现该接口的实例这就是用到了多态的概念。 那么如果写成li.doTask(Chen chen)可以吗 这种方式当然也可以但如果还有Wang、Liu.....等各种实现了CallBack接口的类同样也要调用这个方法呢。那么我是不是就要在li中定义doTask(Wang wang)、doTask(Li li).....各种方法。所以这里就可以看到多态提供的好处了。我们只需要定义接口类型即可具体传入哪个是哪个类型无需关心。因为它绝对是这个接口的实现类。