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