• java回调callback


    callback不在23中设计模式之中,但我觉得它和设计模式一样重要。

    大家都知道异步IO比同步IO性能更好,唯一的问题就是异步IO不能马上获得返回结果。

    一般通过一个callback来获取返回值。我们通过一个简单的异步IO例子,来理解下callback的应用。

    首先我们实现一个客户端,它负责发送消息

    public class AsyncHttpClient {
    
       private Connection connect(String host, int port) {
            return new Connection(host, port);
        }
    
        public void sendMsg(String host, int port, String msg, final InvokeCallback invokeCallback) {
            Connection connection = connect(host, port);
            Command command = new Command(msg);
            boolean sendOk = connection.send(command);
            ResponseFuture future = new ResponseFuture(command,invokeCallback);
            if (sendOk) {
                future.executeInvokeCallback();
            }
        }
    
        public static void main(String[] args) {
            AsyncHttpClient httpClient = new AsyncHttpClient();
            httpClient.sendMsg("hw-node4", 9090, "hello?", new InvokeCallback() {
                @Override
                public void operationComplete(ResponseFuture future) {
                    String s = future.get();
                    System.out.println("receive="+s);
                }
            });
        }
    }

    消息的内容,我们包装了一个Command类

    public class Command {
        private static final AtomicLong idGenerator = new AtomicLong(1);
        private Long requestId;
        private String msg;
    
        public Command(String msg) {
            this.requestId = idGenerator.getAndIncrement();
            this.msg = msg;
        }
    
        @Override
        public String toString() {
            return "msg='" + msg ;
        }
    }

    为了建立和服务端的连接,我们还需要一个Connection类

    public class Connection {
        private String host;
        private int port;
    
        public Connection(String host, int port) {
            this.host = host;
            this.port = port;
            System.out.println("init Connection");
        }
    
        boolean send(Command msg) {
            System.out.println("send=" + msg.toString());
            try {
                Thread.sleep(1000);
                return true;
            } catch (InterruptedException e) {
                e.printStackTrace();
                return false;
            }
        }
    }

    因为是异步IO,所以发送完消息后,会生成一个Future对象。

    理论上Future对象会跟服务端交互,在未来的某一个时刻拿到时间的response,但这里我们没有实际的服务端,所以就简单返回一个OK。

    public class ResponseFuture {
        private final Command msg;
        private final InvokeCallback invokeCallback;
    
        public ResponseFuture(Command msg, InvokeCallback invokeCallback) {
            this.msg = msg;
            this.invokeCallback = invokeCallback;
        }
    
        public String get() {
            return msg + ",ok!";
        }
    
        /**
         * 执行回调函数
         */
        void executeInvokeCallback() {
            invokeCallback.operationComplete(this);
        }
    }

    回调接口也很简单,它给我们返回Future对象

    public interface InvokeCallback {
        void operationComplete(ResponseFuture future);
    }

    这样我们在sendMsg的同时,传入一个InvokeCallback,里面有一个operationComplete方法,方法的内容使我们自定义的。

    一旦我们成功收到response,就会执行这个回调函数。

    另外一种回调的使用场景是前端。

    比如页面上设计了一个按钮,但按钮并不知道用户点击后需要自己干什么,所以还需要传入一个回调函数。里面包着需要做的事情

    Button button = (Button)findViewById(R.id.button);
    button.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        System.out.println("I am clicked.");
      }
    });
  • 相关阅读:
    NoSQL、memcached介绍、安装memcached、查看memcached状态
    报警系统配置文件
    shell中的函数、数组、报警系统脚本
    for循环、while循环、break、continue、exit
    Shell脚本中的逻辑判断、文件目录属性判断、if的特殊用法、case判断
    Shell脚本、Shell脚本结构、date命令的用法、变量
    zabbix的自动发现、自定义添加监控项目、配置邮件告警
    rabbitMQ中的Vhost理解、创建和使用
    charset编码问题:YAMLException: java.nio.charset.MalformedInputException
    java jna 报错:Unable to load library
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/15842222.html
Copyright © 2020-2023  润新知