java回调函数(callBack)

       最近有个新同事给我写了个接口,说是用到了回调,我等了半天发现结果才返回回来,把我都整急了。最后我看了他的代码,目瞪口呆。他还信誓旦旦的说没错,按网上的例子来写的。

       我一搜,网上例子真一大堆,并且都尼玛差不多。

首先,定义写的不错:经理A下班前打电话给程序猿B,叫他加班搞定一个项目,然后经理A就挂了电话,程序猿B加班搞定了整个项目,并打电话告诉了经理A。程序猿B将结果告诉经理A的这个行为就是回调。

      网上有句话叫做什么?应聘造就面试人才!!!这句话真的没错。。。先来看他们的demo(大致如下面写的):

ClassA.java(表示经理A)
package com.example.demo1.dto;

public class ClassA {
    public static void sendCommand(String command){
        ClassB.acceptCommand(command);
    }

    public static void callBack(String str){
        System.out.print(str);
    }
}

ClassB.java(表示程序猿B)

package com.example.demo1.dto;

public class ClassB {
    public static void acceptCommand(String command){
        System.out.print("收到命令:"+command+"\n");
        doSomething(command);
        ClassA.callBack("命令【"+command+"】执行完毕!\n");
    }

    public static void doSomething(String command){
        System.out.print("正在执行命令:"+command+"\n");
    }
}

执行结果:

java回调函数(callBack)_第1张图片

然后再接着还进行了一些抽象封装。

看到上面,我要是经理A,我肯定让你将代码提交一下,然后告诉你不用来上班了!我是卸磨杀驴吗?不是,是你技术太渣!

       为什么这么说呢?明明下了命令后我是是可以约妹子去聊聊人生,聊聊理想的。结果呢,丫的,下了命令,却不能挂电话,还得听你在那啰里吧嗦的,直到你说搞好了。。。

      怎么是这样呢?明明用了回调函数呀!但你有没有发现,你这回调函数用的,跟直接return 没有区别,也就是ClassA.callBack("命令【"+command+"】执行完毕!\n");跟直接 return "命令【"+command+"】执行完毕!\n";的效果一样!!

        我将定义抽象一下,A向B发送请求,B由于执行时间比较长,无法立刻知道结果,就只是告诉A收到你的请求了,然后埋头干活,干完后,再通知A最终的结果。

       这个例子写得是像模像样的,但关键是没整明白,回调主要是用在异步上面,像这样用在同步上面,就没什么意义了。

那该如何改了,很简单,将ClassB.java改一下就好了,更改后代码如下:

package com.example.demo1.dto;

public class ClassB {
    public static void acceptCommand(String command){
        System.out.print("收到命令:"+command+"\n");
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.print("正在执行命令:"+command+"\n");
                ClassA.callBack("命令【"+command+"】执行完毕!\n");
            }
        }).start();
        ClassA.callBack("收到命令【"+command+"】了,马上开始执行!\n");
    }
}

执行结果如下:

java回调函数(callBack)_第2张图片

通过这个,效果就达到了。经理A下班前打电话给程序猿B,叫他加班搞定一个项目,程序猿B说:“收到,马上开干!”,然后经理A挂了电话就约妹去了。然后程序猿B干完了之后,给经理A回了一个电话:"搞定了!"。经理A一想,小伙子靠谱啊,看来得给你加薪了,免得被人挖走了。

 

至于抽象封装就自己搞定哈。

 

       在同一个服务中,上面的回掉是没有任何问题的,但如果是跨系统跨服务,那么该怎么实现回掉呢,毕竟你的class和方法别人是无法拿的到的。这时候,一般可以采用消息推送。IM即时通信系统,推送是很简单的,其他系统,也可以采用消息中间件MQ进行结果的推送,当然,最简单的是增加一个参数,让A请求的时候带上回掉的URL,然后B处理完后,通过Httpclient调用该URL将结果通知A。像微信公众号的模板消息,群发消息结果的通知就是这么干的。

      总之,回调是一种思想,不要拘泥于形式。

你可能感兴趣的:(后端)