Reputation: 143
Need help with understanding the code execution flow.
On calling the sayHi()
method below, the onSuccess
handler is executed first and then the return
statement gets executed.
I had the understanding that the function will return immediately and the onSuccess
handler will get executed after that.
public String sayHi() {
sayHello().onSuccess(s -> {
System.out.println(s);
});
return "hi";
}
public Future<String> sayHello() {
String s1 = "hello";
return Future.succeededFuture(s1);
}
EDIT: I'm trying to draw a comparison it with JavaScript Promises, where the function passed to the then
method always gets executed after the rest of the statements are executed. Like calling the test
method below will print 'hi','bye' and then 'Success'
var promise2 = new Promise((resolve, reject) => {
resolve("Success!")
});
function test() {
console.log("hi");
promise2.then((value) => {
console.log(value);
});
console.log("bye");
}
Upvotes: 2
Views: 373
Reputation: 3121
From the documentation:
You cannot interact directly with the result of a future, instead you need to set a handler that will be called when the future completes and the result is available, like any other kind of event.
So the Future
result is available immediately and there is no I/O task to wait for: like an HTTP response, or reading from file system...etc.
All your code is running in a single thread you can verify it yourself:
public String sayHi() {
sayHello().onSuccess(s -> {
System.out.println("Thread name ==> " + Thread.currentThread().getName()); // e.g: Thread name ==> main
System.out.println(s);
});
return "hi";
}
public Future<String> sayHello() {
System.out.println("Thread name ==> " + Thread.currentThread().getName()); // e.g: Thread name ==> main
String s1 = "hello";
return Future.succeededFuture(s1);
}
But the code below may run in different order (we are doing I/O task here):
public String sayHi() {
sayHello().onSuccess(s -> {
System.out.println(s);
});
return "hi";
}
public Future<String> sayHello() {
var vertx = Vertx.vertx();
var fs = vertx.fileSystem();
return fs.props( ".").map(fileProps -> "In getHelloFuture() method"); // I/O task
}
Upvotes: 0
Reputation: 21435
The problem is that Future.succeededFuture(s1)
returns an already completed Future
that is not associated with an ExecutionContext.
Since it is already completed and not associated with an ExecutionContext it executes the onSuccess()
handler synchronously.
You need to tell vert.x to create the Future<String>
for you on a separate thread. You can try
import io.vertx.core.Future;
import io.vertx.core.Vertx;
public class Async {
private static Vertx vertx;
public static void main(String[] args) {
vertx = Vertx.vertx();
System.out.println(sayHi());
vertx.close();
}
public static String sayHi() {
sayHello().onSuccess(s -> {
System.out.println(s);
});
return "hi";
}
public static Future<String> sayHello() {
return vertx.executeBlocking(p -> {
String s1 = "hello";
p.complete(s1);
});
}
}
Note: I don't have much experience with vert.x, so there could be better approaches.
Upvotes: 1