Java pattern for nested callbacks?

后端 未结 4 679
滥情空心
滥情空心 2020-12-12 19:30

I\'m looking for a Java pattern for making a nested sequence of non-blocking method calls. In my case, some client code needs to asynchronously invoke a service to perform s

相关标签:
4条回答
  • 2020-12-12 19:40

    You can use actor computing model. In your case, the client, services, and callbacks [B-D] all can be represented as actors.

    There are many actor libraries for java. Most of them, however, are heavyweight, so I wrote a compact and extendable one: df4j. It considers actor model as a specific case of more general dataflow computing model and, as a result, allows user to create new types of actors, to optimally fit user's requirements.

    0 讨论(0)
  • 2020-12-12 19:44

    I am not sure if I get you question correctly. If you want to invoke a service and on its completion result need to be passed to other object which can continue processing using result. You can look at using Composite and Observer to achive this.

    0 讨论(0)
  • 2020-12-12 19:50

    Since the implementation (not only the interface) must not block, I like your list idea.

    Set up a list of "operations" (perhaps Futures?), for which the setup should be pretty clear and readable. Then upon receiving each response, the next operation should be invoked.

    With a little imagination, this sounds like the chain of responsibility. Here's some pseudocode for what I'm imagining:

    public void setup() {
        this.operations.add(new Operation(new RequestA(), new CallbackA()));
        this.operations.add(new Operation(new RequestB(), new CallbackB()));
        this.operations.add(new Operation(new RequestC(), new CallbackC()));
        this.operations.add(new Operation(new RequestD(), new CallbackD()));
        startNextOperation();
    }
    private void startNextOperation() {
        if ( this.operations.isEmpty() ) { reportAllOperationsComplete(); }
        Operation op = this.operations.remove(0);
        op.request.go( op.callback );
    }
    private class CallbackA implements Callback<Boolean> {
        public void onSuccess(Boolean response) {
            // store response? etc?
            startNextOperation();
        }
    }
    ...
    
    0 讨论(0)
  • 2020-12-12 20:03

    In my opinion, the most natural way to model this kind of problem is with Future<V>.

    So instead of using a callback, just return a "thunk": a Future<Response> that represents the response that will be available at some point in the future.

    Then you can either model subsequent steps as things like Future<ResponseB> step2(Future<ResponseA>), or use ListenableFuture<V> from Guava. Then you can use Futures.transform() or one of its overloads to chain your functions in a natural way, but while still preserving the asynchronous nature.

    If used in this way, Future<V> behaves like a monad (in fact, I think it may qualify as one, although I'm not sure off the top of my head), and so the whole process feels a bit like IO in Haskell as performed via the IO monad.

    0 讨论(0)
提交回复
热议问题