ASM END block how to wait for the result

Hi,

Question like in topic, I have asm end block is it possible to wait for the block end?
Can I use some await for this

example

begin
control.hide;
asm
some code
end
// wait for code ending inside the asm block
control.show;
end;

Within an ASM block, you have JavaScript code, so , you would need to use the JavaScript await() construct in this code block. Mark the procedure from where you use this ASM block with the async decoration.

See also:

Ok ... why it doesn't wait for the await function


interface

uses
  System.SysUtils, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls,
  WEBLib.Forms, WEBLib.Dialogs, Vcl.Controls, Vcl.StdCtrls, WEBLib.StdCtrls;

type
  TForm1 = class(TWebForm)
    wbtn2: TWebButton;
    [Async] procedure wbtn2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    [Async] procedure testawait();
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.testawait;
begin
  asm
    await(setTimeout(function () {
      alert('After 5 seconds')
    }, 5000));
  end;
end;

procedure TForm1.wbtn2Click(Sender: TObject);
begin
  Await(testawait);
  ShowMessage('Should be show at the end');
end;

end.

Why It doesn't wait for the end of testwait procedure and 'Should be show at the end' is displayed without waiting.
Could you look into the attached project ?

TestAwaitAsm.zip (1.6 MB)

If setTimeout is not good idea ... you can replace this like below

procedure TForm1.testawait;
begin
  asm
    async function delay() {
      console.log("Start");
      await new Promise(resolve => setTimeout(resolve, 5000));
      console.log("Waited for 5 seconds");
      console.log("End");
    }
    delay();
  end;
end;

the effect is exactly the same

Hi @brunofierens any comments on this topic?

An await has effect on functions returning promises only. Your testawait function does not return a promise, so it cannot be awaited for.

Ok ... than in attachment project with promises and two functions with and without asm block inside.

function TForm1.testawaitwithasmblock():TJSPromise;
begin
  Result := TJSPromise.new(procedure(ASuccess, AFailed: TJSPromiseResolver)
  begin
    asm
      async function delay() {
        await new Promise(resolve => setTimeout(resolve, 5000));
          console.log('done delay() with asm block');
        }
      delay();
    end;
    ASuccess('done with asm block');
  end);
end;

function TForm1.testawaitwithoutasmblock: TJSPromise;
begin
  Result:=TJSPromise.new(procedure(ASuccess, AFailed : TJSPromiseResolver)
    begin
      window.setTimeout(procedure
        begin
          ASuccess('done without asm block');
        end,
      2000);
    end);
end;

The output for the function without asm block is ok:
image

but for function with asm is bad:
image

Could you point me what is wrong, and why the code line

ASuccess('done with asm block');

doesn't wait for the asm block finish?
TestAwaitAsmVersion2.zip (1.6 MB)

You call Success() in the ASM block immediately & unconditionally

@Bruno_Fierens ok I found the problem the delay function should be run with await like this:

function TForm1.testawaitwithasmblock():TJSPromise;
begin
  Result := TJSPromise.new(procedure(ASuccess, AFailed: TJSPromiseResolver)
  begin
    asm
      async function delay() {
        await new Promise(resolve => setTimeout(resolve, 5000));
          console.log('done delay() with asm block');
        }
      await delay();
    end;
    ASuccess('done with asm block');
  end);
end;

but the problem is that I have no possibility to mark anonymous finction as async.

When I did this like:

 Result := TJSPromise.new([async] procedure(ASuccess, AFailed:

it is error during compilation.

Do you know how can I do this in Delphi in this case ? ... the generated js script should contain async before Promise function:

pas2js transpiler doesn't support this attribute in params yet.
pas2js team consider this for a future version.

Ok ... than solution which is working we can do without anonymous procedure

procedure TForm1.promisout(resolve,reject : TJSPromiseResolver);
begin
  asm
    async function delay() {
        await new Promise(resolve => setTimeout(resolve, 5000));
          console.log('done delay() with asm block');
        }
    await delay();
  end;
  resolve('done with asm block');
end;

function TForm1.promisouttest: TJSPromise;
begin
  Result := TJSPromise.new(@promisout);
end;

and run in this way

procedure TForm1.wbtn1Click(Sender: TObject);
var
  s: string;
begin
  console.log('calling test start');
  s := await(string,promisouttest());
  console.log(s);
  console.log('calling test end');
end;

thanks @brunofierens for your patience :slight_smile:

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.