Vertx - Future.compose

1.vertx中的Future與java原生中不同,二者都有封裝結(jié)果的功能,但是vertx中為了避免await阻塞event loop線程,導(dǎo)致不能及時(shí)響應(yīng)的問題.通過在Future中定義回調(diào)Handler來解決這個(gè)問題.
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.定義一個(gè)結(jié)果類型為String的Future.
2.為這個(gè)Future設(shè)置回調(diào).
3.調(diào)用異步方法,將這個(gè)Future作為參數(shù)傳入
4.complete()將調(diào)用結(jié)果封裝進(jìn)Future,并將Future的狀態(tài)置為completed.返回.
5.最后回調(diào)函數(shù)執(zhí)行,處理調(diào)用結(jié)果.

需要理清的是,
Future<T> 中的T代表的是返回的結(jié)果類型.
Handler<AsyncResult<T>> 是對(duì)調(diào)用結(jié)果的處理函數(shù).

2.理解compose,compose是為了應(yīng)對(duì)回調(diào)地獄采用的鏈?zhǔn)綄懛?
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.下一個(gè)future

處理思路:
1.執(zhí)行compose調(diào)用future的回調(diào)處理
2.如果當(dāng)前future的回調(diào)處理中出錯(cuò),那么將下一個(gè)future置為失敗,
3.未出錯(cuò)則直接將下一個(gè)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個(gè)future
2.第4行模擬第1個(gè)異步調(diào)用完畢,f1得到結(jié)果,狀態(tài)completed.
3.f1發(fā)起compose,參數(shù)1為f1的handler,參數(shù)2為下一個(gè)future f2
4.注意,在f1的handler中,模擬第2個(gè)異步調(diào)用完畢,f2狀態(tài)轉(zhuǎn)為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>>,說明傳入的是一個(gè)轉(zhuǎn)換函數(shù),此函數(shù)將future中的調(diào)用結(jié)果T轉(zhuǎn)換為鏈中的下一個(gè)future.
2.如果調(diào)用是成功的,那么將調(diào)用結(jié)果作為參數(shù)傳入這個(gè)function執(zhí)行,就是這句"apply = mapper.apply(ar.result());",返回結(jié)果為Future<U>.
3.由于事先需要對(duì)調(diào)用結(jié)果ar是否成功判斷,所以外面再套了個(gè)Future<U> ret.
4.將ret返回.
這個(gè)封裝蠻有意思,在compose方法中設(shè)置調(diào)用者future的handler,在handler中將future中的結(jié)果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封裝復(fù)雜了些,但是使用過程比第1種寫法更加簡單了.也容易理解.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容