pas2js AsyncAWait
From Free Pascal wiki
Overview
Pas2js supports the JS operators async/await to simplify the use of Promise, which itself simplifies writing asynchronous code, like starting a download, waiting for the result, then depending on the result start the next and so forth. Instead of writing a tedious and hard to read mass of sub functions an async procedure can be written in the common serial aka imperative way.
AWait
Pas2js provides a built-in await function, which supports three flavours:
function await(AsyncFunctionOfResultTypeT): T;
function await(aType; p: TJSPromise): aType; // explicit promise requires the resolved type
function await(const Expr: T): T; // implicit promise
The await function can only be used inside a procedure with the async modifier.
An async procedure can contain multiple await calls.
Example Async try fetch
Example demonstrating waiting for an async function, catching errors with a try..except and no anonymous functions.
// Translated from https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await
program askmom;
{$mode objfpc}
uses
browserconsole, JS, Web, SysUtils;
procedure myFetch; async;
var
response: TJSResponse;
myBlob: TJSBlob;
image: TJSHTMLImageElement;
objectURL: string;
begin
try
response := await(window.fetch('test1.png'));
if not response.ok then
raise Exception.Create('HTTP error! status: '+str(response.status))
else begin
myBlob := await(response.blob());
objectURL := URL.createObjectURL(myBlob);
image := TJSHTMLImageElement(document.createElement('img'));
image.src := objectURL;
document.body.appendChild(image);
end;
except
console.log(JSExceptValue);
end;
end;
begin
myFetch;
end.
Example Wait 2 Seconds
Program MyModule;
uses JS, Web;
function ResolveAfter2Seconds: TJSPromise;
// returns immediately with a Promise,
// which after 2 seconds gets resolved
begin
Result:=TJSPromise.new(procedure(resolve, reject : TJSPromiseResolver)
begin
window.setTimeout(procedure
begin
resolve('resolved');
end,
2000); // wait 2 seconds
end);
end;
procedure AsyncCall; async;
var s: string;
begin
writeln('calling');
s := await(string,resolveAfter2Seconds());
// the await pauses this procedure returning to the caller
// when the Promise from resolveAfter2Seconds gets resolved
// this procedure is continued
writeln(s); // expected output: 'resolved'
end;
begin
AsyncCall;
// calling AsyncCall returns immediately, while the Promise is waiting
writeln('called');
end.
Expected output:
calling called resolved