ExecuteAsync(ACompletionHandler: TCompletionHandler = nil; ASynchronized: boolean = true; AFreeThread: boolean = true)
方法確實是要走的路。顧名思義,它是異步的;意味着您的程序在發出請求後仍然響應,或者甚至在發出多個請求之後。
但是,從不同的對象實例中引發這些不同請求是很重要的;如果您從已經執行ExecuteAsync
的TRESTRequest
實例中觸發ExecuteAsync
,則新請求將妨礙現有請求。您必須爲每個並行呼叫創建一個單獨的TRESTRequest
實例。
請注意,它的第一個參數是一個過程;你傳遞一個你選擇的程序作爲參數。唯一的要求是程序有正確的簽名;在這種情況下,它是一個沒有參數的過程。
ExecuteAsync方法在REST.Client
中定義。 (我有德爾福XE-10.1柏林,所以它有一個額外的參數,ACompletionHandlerWithError
- 這被稱爲錯誤。原則保持不變)。
讓我們一起來看看:
function TCustomRESTRequest.ExecuteAsync(ACompletionHandler: TCompletionHandler = nil; ASynchronized: boolean = true;
AFreeThread: boolean = true; ACompletionHandlerWithError: TCompletionHandlerWithError = nil): TRESTExecutionThread;
begin
Result := TRESTExecutionThread.Create(Execute, self, ACompletionHandler, ASynchronized, AFreeThread, ACompletionHandlerWithError);
end;
這裏會發生什麼事是,一個新的線程被創建在其中執行的REST請求。如果響應進入,則由ACompletionHandler
處理。
默認情況下,ACompletionHandler
在由ExecuteAsync
創建的新線程上運行。如果您希望它在主線程上運行,則應將ASynchronized
設置爲true
。
但是,您如何訪問該響應,並使其可以訪問您的程序的其餘部分?
FireMonkey的TRESTRequest類有一個屬性Response
,它指向包含服務器對我們請求的響應的TRESTResponse對象。
不幸的是,TRESTRequest和TRESTResponse對象都不會傳遞給我們的CompletionHandler!
所以我們需要以某種方式給CompletionHandler這個信息。幸運的是,我們可以使用一個方法作爲CompletionHandler。
我們假設要處理結果數據的類被稱爲DataOwner
。我們的目的是DataOwner
有權訪問與TRESTRequest實例關聯的TRESTResponse實例。
要做到這一點最簡單的方法就是讓TRESTRequest和/或TRESTResponse的DataOwner
成員。
假設你的請求是從一個名爲MyRESTRequest
一個TRESTRequest實例觸發和處理功能processResponse
,你可以使用下面的代碼:
type TDataOwner = class
MyData: TSomeDataType;
procedure GetData();
procedure FillDataSet();
end;
implementation
procedure DataOwner.GetData();
begin
// ... initialize MyRESTRequest here...
MyRESTRequest.ExecuteAsync(FillDataSet);
end;
procedure DataOwner.FillDataSet();
begin
MyData := processResponse(MyRESTRequest.Response);
end;
如果你想火併聯多個請求,則需要使用這種模式幾次。不幸的是,我們沒有直接訪問我們的完成處理程序中的TRESTRequest實例或TRESTResponse實例,因爲這意味着我們必須自己做記賬。換句話說,程序員要確保完成處理程序處理正確的響應對象。
@JerryDodge不是異步暗示它不會阻止?最終,異步操作將終止,並且應用程序可以對結果進行一些操作。 – mjn 2014-12-03 19:31:17
@mjn這個按鈕點擊我們將調用這7個Web服務的地方實際上會打開一個多視圖,在我們的例子中將包含一堆過濾組合框,這些組合框將通過從Web服務獲取數據來填充。我的想法是讓用戶能夠實際取消該過濾,然後通過觸摸多視圖之外的區域返回,這將關閉多視圖並且不應用任何過濾器。多個並行請求的想法是,如果我們並行發送7個請求,而不是一次發送一個請求,那麼我們認爲這7個組合框將更快地填充。 – Emulic 2014-12-03 21:36:45
@JerryDodge您應該在後臺執行** all ** long(er)正在運行的任務,以防止UI線程被阻塞。這不僅是爲用戶,而且操作系統正在尋找沒有響應的應用程序。 – 2014-12-03 23:29:41