Introducing "Await" for Closure Callbacks
In today's Elements build, .2417, we're extending await
support to methods with closure callbacks – such as the many Cocoa APIs.
"Async/Await" is a great pattern, pioneered by C# and adopted by many other languages, including Oxygene, JavaScript and others for making asynchonous code easier to write and understand. But thew downside has been that APIs had to be designed especiually for async/await.
Many platforms, including Cocoa and Android, have a rich existing API based around passing callback closures or methods to APIs. The async call will return right away, and call the closure when done. Up until today, these APIs have bene incompatible with the more advanced await
pattern. Until today.
Consider a piece of code like this:
method DownloadData;
begin
Http.ExecuteRequestAsJson(new HttpRequest(URL), (aResponse) -> begin
if assigned(aResponse.Content) then begin
dispatch_async(dispatch_get_main_queue(), () -> begin
fData := aResponse.Content;
tableView.reloadData;
end);
end;
end);
end;
This code uses two nested closures, first to wait for the response of the network request, and then to process its results on the main UI thread. With the new await
support for closure callbacks, this can be simplified nicely:
method DownloadData;
begin
var lResponse := await Http.ExecuteRequestAsJson(new HttpRequest(URL));
if lassigned(aResponse.Content) then begin
await dispatch_async(dispatch_get_main_queue());
fData := lResponse.Content;
tableView.reloadData;
end;
end;
The same of course works in RemObjects C# (which has the await
keyword by standard), and also in our version of Swift, with its __await
language extension:
func downloadData() {
let response = __await Http.ExecuteRequestAsJson(HttpRequest(URL)) {
if let content = response.Content {
__await dispatch_async(dispatch_get_main_queue())
data := response.Content
tableView.reloadData()
}
}
Just as with standard async/await, the compiler will do the hard part of taking apart the surrounding code and wrap what looks like linear code flow into multiple helper methods that will be called under the hood as needed. And of course await
for Closure Callbacks works for more complex nexted code structures as well, such as making an await call nested within conditional if
statements or loops, or even as part of a parameter list:
print(await getServerResponse())
Await for Closure Callbacks is new in Elements .2417, available now. You can read more about the feature on our documentation site, here.