1.vertx中的Future與java原生中不同,二者都有封裝結果的功能,但是vertx中為了避免await阻塞event loop線程,導致不能及時響應的問題.通過在Future中定義回調(diào)Handler來解決這個問題.
demo1:
private static void asynchronousMethod(Future<String> f){
f.complete("haha");
}
public static void main(String[] args) {
Future<String> future = Future.future();
future.setHandler(r -> {
System.out.println("result is:" + r);
});
asynchronousMethod(future);
}
demo1解釋:
1.定義一個結果類型為String的Future.
2.為這個Future設置回調(diào).
3.調(diào)用異步方法,將這個Future作為參數(shù)傳入
4.complete()將調(diào)用結果封裝進Future,并將Future的狀態(tài)置為completed.返回.
5.最后回調(diào)函數(shù)執(zhí)行,處理調(diào)用結果.
需要理清的是,
Future<T> 中的T代表的是返回的結果類型.
Handler<AsyncResult<T>> 是對調(diào)用結果的處理函數(shù).
2.理解compose,compose是為了應對回調(diào)地獄采用的鏈式寫法.
compose的第一種寫法:
default <U> Future<U> compose(Handler<T> handler, Future<U> next) {
setHandler(ar -> {
if (ar.succeeded()) {
try {
handler.handle(ar.result());
} catch (Throwable err) {
if (next.isComplete()) {
throw err;
}
next.fail(err);
}
} else {
next.fail(ar.cause());
}
});
return next;
}
傳入?yún)?shù)為
1.調(diào)用此compose方法的future的handler,
2.下一個future
處理思路:
1.執(zhí)行compose調(diào)用future的回調(diào)處理
2.如果當前future的回調(diào)處理中出錯,那么將下一個future置為失敗,
3.未出錯則直接將下一個future返回.
demo2:
Future<String> f1 = Future.future();
Future<Integer> f2 = Future.future();
f1.complete("f1's result");
f1.compose(r -> {
System.out.println("f1 handler:" + r);
f2.complete(123);
} , f2).setHandler(r -> {
System.out.println("f2 handler:" + r.result());
});
demo2解釋:
1.定義2個future
2.第4行模擬第1個異步調(diào)用完畢,f1得到結果,狀態(tài)completed.
3.f1發(fā)起compose,參數(shù)1為f1的handler,參數(shù)2為下一個future f2
4.注意,在f1的handler中,模擬第2個異步調(diào)用完畢,f2狀態(tài)轉為completed,從而觸發(fā)f2的handler.
compose的第2種寫法
default <U> Future<U> compose(Function<T, Future<U>> mapper) {
if (mapper == null) {
throw new NullPointerException();
}
Future<U> ret = Future.future();
setHandler(ar -> {
if (ar.succeeded()) {
Future<U> apply;
try {
apply = mapper.apply(ar.result());
} catch (Throwable e) {
ret.fail(e);
return;
}
apply.setHandler(ret);
} else {
ret.fail(ar.cause());
}
});
return ret;
}
處理思路:
1.傳入?yún)?shù)類型Function<T, Future<U>>,說明傳入的是一個轉換函數(shù),此函數(shù)將future中的調(diào)用結果T轉換為鏈中的下一個future.
2.如果調(diào)用是成功的,那么將調(diào)用結果作為參數(shù)傳入這個function執(zhí)行,就是這句"apply = mapper.apply(ar.result());",返回結果為Future<U>.
3.由于事先需要對調(diào)用結果ar是否成功判斷,所以外面再套了個Future<U> ret.
4.將ret返回.
這個封裝蠻有意思,在compose方法中設置調(diào)用者future的handler,在handler中將future中的結果ar傳遞給compose參數(shù)(function),然后執(zhí)行function,最后將function返回的future用compose內(nèi)部生成的future封裝下返回.
demo3:
Future<String> f1 = Future.future();
f1.complete("f1's result");
f1.compose(r -> {
System.out.println(r);
Future<String> f2 = Future.future();
f2.complete("f2's result");
return f2;
}).compose(r -> {
System.out.println(r);
Future<String> f3 = Future.future();
f3.complete("f3's result");
return f3;
}).setHandler(r -> {
System.out.println(r.result());
});
雖然api封裝復雜了些,但是使用過程比第1種寫法更加簡單了.也容易理解.