簡體   English   中英

Java中的多個異步請求處理

[英]Multiple asynchronous request handling in java

我正在寫android應用程序,它使用一些站點api。 該站點提供了一些用於處理此api的SDK。 我正在用它向網站提出一些要求。
因此,要發出請求,我應該這樣做:

VKRequestListener listener = new VKRequestListener(){
    @Override
    public void onComplete(VKResponse response){
      // do smth when response is complete
    }
}
VKRequest vkRequest = new VKRequest("request", "parameters");
vkRequest.executeWithListener(listener);

listener異步運行,因此,如果我發出單個請求,一切都會很好:我可以在onComplete方法中處理它。 但是,如果我需要發出多個請求,而且每個下一個請求都取決於先前的響應,該怎么辦? 我只看到兩種方法,兩種方法看起來都很糟糕:
1. 使用onComplete方法發出每個下一個請求。 這似乎過於嵌套和不靈活。
2.進行 某種同步操作:在主線程執行請求之后,以某種方式檢查onComplete執行(btw,如何?使用某種標志對象?),否則,執行Thread.sleep(1000) ,重復此操作直到返回響應,而不是做出其他回應。
因此,請告訴我是否有“正常”方式來處理多個異步請求?

Java中的Multiple Async確實很難看,太多樣板了。 以下是如何手動滾動所需內容的方法。 但我建議也研究圖書館。

#1解決方案

如果很好地分解了代碼,這里就沒有嵌套(至少不是很明顯):如果已經有了必要的數據,甚至可以在鏈的中間開始。 基本上,您可以基於VK類創建自己的異步接口,但VK完全隱藏。

class MyRequests {
    interface GetStuffResult {
        void done(String result, float result2);
        // you can even put other callbacks here to help make decisions in the chain
        // based on UI element states for example
    }

    static void startGetStuff1(String param1, String param2, final GetStuffResult result) {
        VKRequestListener listener = new VKRequestListener(){
            @Override
            public void onComplete(VKResponse response){
                // extract parameters for next request 
                String newParameter1 = ...;
                int newParameter2 = ...;
                startGetStuff2(newParameter1, newParameter2, result);
            }
        };
        VKRequest vkRequest = new VKRequest("request", buildParameters1(param1, param2));
        vkRequest.executeWithListener(listener);
    }

    static void startGetStuff2(String param1, int param2, final GetStuffResult result) {
        VKRequestListener listener = new VKRequestListener(){
            @Override
            public void onComplete(VKResponse response){
                // extract parameters for next request 
                startGetStuff3(newParameter1, newParameter2, newParameter3, result);
            }
        };
        VKRequest vkRequest = new VKRequest("request", buildParameters2(param1, param2));
        vkRequest.executeWithListener(listener);
    }

    static void startGetStuff3(String param1, int param2, Date param3, final GetStuffResult result) {
        VKRequestListener listener = new VKRequestListener() {
            @Override
            public void onComplete(VKResponse response) {
                // extract result
                result.done(resultingString, resultingFloat);
            }
        };
        VKRequest vkRequest = new VKRequest("request", buildParameters3(param1, param2, param3));
        vkRequest.executeWithListener(listener);
    }
}

#2解決方案

要使異步請求同步,您可以執行以下操作:
只能在后台線程上執行此操作! 還要注意, AsyncTask按1的AsyncTask執行任務,因此,如果將其放在AsyncTask它將阻止其他異步任務執行!

final AtomicReference<VKResponse> result = new AtomicReference<>();
final CountDownLatch latch = new CountDownLatch(1);
VKRequestListener listener = new VKRequestListener(){
    @Override
    public void onComplete(VKResponse response){
        result.set(response);
        latch.countDown();
    }
};
VKRequest vkRequest = new VKRequest("request", "parameters");
vkRequest.executeWithListener(listener);    
// call countDown() even if the request fails if you have an error callback as well!
// and check the existence of response/flag you set if it failed

try {
    latch.await();
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
}
VKResponse response = result.get(); // will be null if interrupted
// do smth when response is complete

對中斷!

您應該嘗試使用Java中的反應性擴展RxJava實現。 它允許通過可觀察對象以非常簡單的方式來組成異步調用。 還有一個android擴展RxAndroid ,可讓您訪問android調度程序以及活動或片段生命周期感知的可觀察對象。

關於在Android上使用Rx的教程和文章很少,但是您應該簽出Dan Lew的教程和文章,因為它涵蓋了您需要的所有東西。 鏈接在這里: Grokking RxJava

我很多時候都在考慮簡單的解決方案,而我做到了:

class RequestFlags{
    int requestCount;
    Params params;
};
private final RequestFlags requestFlags;

public requestWrapper(RequestFlags rf){
    VKRequestListener listener = new VKRequestListener(){
        @Override
        public void onComplete(VKResponse response){
        // do smth when response is complete
             if(requestFlags.requestCount != 0) {
                 requestFlags.requestCount--;
                 requestFlags.params = doSmth(response);
                 requestWrapper(requestFlags);
             } else{
                 // we finished - do smth on finish
             }
        }
    }
    Params someParams;
    switch(requestFlags.params){
        case param1: someParams = doSmthElse();
        break;
        case param2: someParams = null;
        break;
        // etc, etc...
    }
    VKRequest vkRequest = new VKRequest("request", someParams);
    vkRequest.executeWithListener(listener);        
}

因此,此請求包裝程序將以遞歸方式調用自身,直到所有請求均連貫且謹慎地處理為止。希望這對某些人有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM