异步完成创建的 Java 对象 - 对象在构造函数完成后的某个时间准备就绪

标签 java asynchronous future

我必须将专有的 java api 包装成更有用的东西。中心类是一个“客户”对象 签名是这样的:

public class ProprietaryClient {

    private final IEvents eventHandler;
    private Object one;
    private Object two;

    public ProprietaryClient(ProprietaryClient.IEvents eventHandler){
        this.eventHandler = eventHandler;
    }

    //returns immediately
    public void connect(String url){
        //doing nasty stuff that triigers
        //on success
        //will be called from somewhere at anytime
        // eventHandler.onStateChange( State.CONNECTED );
    }

    //returns immediately
    public void login(String user, String password){
        //doing nasty stuff that sets fields one and two
        //will be called from somewhere at anytime
        //eventHandler.onStateChange( State.LOGGED_IN );
        //eventHandler.onLogin( one, two );
    }

    public interface IEvents {

        void onStateChange(State state);

        void onLogin(Object one, Object two);
    }

    public enum State{
        CONNECTED,
        LOGGED_IN,
        UNKNOWN;
    }
}

此对象仅在“LOGGED_IN”状态下有用,但此字段没有 getter。知道对象是否可用的唯一方法是:

  1. 调用连接
  2. 等待状态更改为 CONNECT
  3. 调用登录
  4. 等待状态更改为 LOGGED_IN(或调用 onLogin)

我想将它包装到一个类中,该类在构造函数中进行连接和登录,并告诉用户它是否准备就绪。 我的想法是有一个返回 CompletableFuture 或 Future 的方法: 这是我到目前为止所拥有的。事件的内容就是这样工作的。 IEvents 的实现将所有事件包装到由用户识别的消息中(这部分正在运行)。 但是如何根据到达的事件创建和维护 CompletableFuture(带有///????? 的部分) 有没有一种方法可以创造我自己的 future ,以便在事件到来或满足正确条件时做好准备?

public class MyClient implements Client, MessageHandler {


    private final String password;
    private final IEvents eventHandler;
    private final SubscribableChannel eventBus;
    private final String user;
    private final ProprietaryClient propClient;

    public SikomClient( String user, String password, IEvents eventHandler, SubscribableChannel eventBus) {
        this.eventHandler = checkNotNull( eventHandler );
        this.eventBus = checkNotNull( eventBus );
        eventBus.subscribe( this );
        this.password = password;
        this.user = user;
        propClient = new ProprietaryClient(eventHandler);
        ///????
        propClient.connect("url");
        //have to wait until message received and state is "CONNECT"
        propClient.login(user, password);

    }

    public CompletableFuture<Boolean> amIready(){
        //???
    }

    @Override
    public void handleMessage( Message<?> message ) throws MessagingException {
        if( message instanceof OnClientStateMessage && belongsToMe( message )){
            // ????
        } else if( message instanceof OnLoginMessage && belongsToMe( message )) {
            // ????
            //complete CompletableFuture with true
        }
    }

    private boolean belongsToMe(Message<?> message){
        return ((AbstractStringJsonMessage) message).getUserId().equals( user );
    }
}

或者有没有更好的方法来解决这个没有“ future ”的问题。我想让调用者负责等待多长时间,但我的类应该保持状态并了解它。

最佳答案

解决方法很简单。现在我对“CompletableFuture”有了更好的理解。

我添加了一个登录方法,一个具有 Completable future 的字段和一个 getter:

private CompletableFuture<ReturnCode> loggedIn = new CompletableFuture<>();
...
private void login() {
    //as per sikom settings each user gets a fixed workplace identified by user name
    if( loggedIn.isDone() ) {
        loggedIn = new CompletableFuture<>();
    }
    propClient.login( user, user, password, 0 );
}

public CompletableFuture<ReturnCode> loggedIn() {
    return loggedIn;
}

我的 handleMessage 是这样做的:

public void handleMessage( Message<?> message ) throws MessagingException {
    if( message instanceof OnClientStateMessage && belongsToMe( message ) ) {
        state = ( (OnClientStateMessage) message ).getState();
        if( state.equals( ClientState.CONNECT ) ) {
            login();
        }
    } else if( message instanceof OnLoginMessage && belongsToMe( message ) ) {
        ReturnCode rc = ( (OnLoginMessage) message ).getRc();
        loggedIn.complete( rc );
    }
}

如果消息到达,我只是手动完成 future (因为它没有附加任务,get 永远不会返回)。

这个类的用户将实例化它并可以立即调用 loggedIn。调用者可以决定等待 loggedIn.get() 的时间。

不知道这是不是个好主意:它自己的类可以扩展 CompletableFuture 并可以完成自身?!

关于异步完成创建的 Java 对象 - 对象在构造函数完成后的某个时间准备就绪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48627057/

相关文章:

scala - future [A] 与 future [Throwable\/A]

java - Material 范围栏 : setOnRangeBarChangeListener method

java - 如何将助记符放在角色的第二个实例(Java-Swing)下?

multithreading - Clojure并行计算数组

javascript - 从多个 url 获取模型时如何渲染 View

c# - 如何处理在一个平台上同步但在另一个平台上异步的代码

scala - 对 future 作出 react

java - SQL插入表错误

java - 无法读取 JSON : Cannot construct instance of `java.util.LinkedHashMap`

c# - 如何在不阻塞主线程的情况下调用同步异步函数?