Vert.x is highly asynchronous. Most operations will actually return immediately, but their results will be available to Handler at a later point in time. So far, so good. If I understand you correctly, you need to call B in Handler from A In this case, A needs to be completed, and the result will be available before calling B :
callA(asyncResultA -> { System.out.println("Result A: " + asyncResultA.result()); callB(asyncResultB -> { System.out.println("Result B:" + asyncResultB.result()); }); });
But you are trying to do something asynchronous. You cannot and should not try to make the asynchronous result available in the main program stream - this will not work.
String respFromApiA = Call_API_A(request); // STEP 1 Response respFromApiB = Call_API_B(request, respFromApiA); // STEP 2 Print(respFromApiB); // PRINT FINAL Response return respFromApiB; // STEP 3
Call_API_A cannot really return the result because it is evaluated asynchronously. The result is available only for Handler Call_API_A (see My example above). The same goes for Call_API_B - so you cannot return the result of Call_API_B . The caller of your class will also have to call your class using the Handler .
Now add some additional information. In your case, you have a problem that several asynchronous results depend on each other. Vert.x provides a much more convenient way to handle asynchronous results - the so-called Futures . A Future (sometimes called Promise , but in the Java world, which they call Future ), is a placeholder for the results of asynchronous calls. Read about them in the documentation .
With Future you can do something like this:
Future<...> callAFuture = Future.future(); callA(asyncResultA -> { if (asyncResultA.succeeded()) { System.out.println("A finished!"); callAFuture.complete(asyncResultA.result()); } else { callAFuture.fail(asyncResultA.cause()); } });
Therefore, instead of trying to return the asynchronous result of B synchronously, you should return Future so that the class you are calling can register for the asynchronous result of both A and B
Hope this helps.
Edit: Future as return value
Suppose you want to wrap callA so that you can work with Future . You can do it as follows:
public Future<String> doSomethingAsync() { Future<String> callAFuture = Future.future(); // do the async stuff callA(asyncResultA -> { if (asyncResultA.succeeded()) { System.out.println("A finished!"); callAFuture.complete(asyncResultA.result()); } else { callAFuture.fail(asyncResultA.cause()); } }); // return Future with the asyncResult of callA return callAFuture; }
A call to this function can use the future as follows:
Future<String> doSomethingFuture = doSomethingAsync(); doSomethingFuture.setHandler(somethingResult -> {
It is also possible to make several Future if you want to make them at the same time, but they are not dependent on each other:
CompositeFuture.all(futureA, futureB).setHandler(connections -> { // both Futures completed });
If you are working in an asynchronous environment such as Vert.x, most of the time you are working with the aka Future result file. And in Handler Future you often make another asynchronous call. You wrap Future with Future , like the callB example in the callA Handler .
How would you return an asynchronous Future result as an HTTP response? Like this:
router.route("/").handler(routingContext -> { HttpServerResponse response = routingContext.response(); Future<String> future = doSomethingAsync(); future.setHandler(somethingResult -> { if (somethingResult.succeeded()) { response .end(somethingResult.result()); } else { routingContext.fail(500); } }); });