Passing an async procedure as argument

Hi,

I have a scenario akin to the following:

type
  TForm = class(TObject)
      [async] procedure MyProcedure;
      constructor create;override;
end;

implementation

constructor TForm.create;
var
    Obj:TOtherForm;
begin
    Obj:=TOtherForm.create(MyProcedure);    
end;
type
  TOtherForm = class(TObject)
      MyProcedure:TProc;
      constructor create(ProcPoint:TProc);
end;

implementation

constructor TOtherForm.create(ProcPoint:TProc);
begin
    Self.MyProcedure:=ProcPoint;
end;

Basically, I pass an async procedure to an object, which can then later be called with await();

Previously this scenario would compile. I don't know under which Web Core version this was running, but having since updated I am now presented with the error message: Got "TJSPromise", expected "TProc".

Is this expected behaviour? If so, what alternative method could I use?
I did try to rewrite the code to return a TJSPromise and pass this, but though it compiled, the promise simply runs immediately.

The code as provided doesn't compile because of

  TForm = class(TObject)
      [async] procedure MyProcedure;
      constructor create; override;  <- error here
  end;

[Error] Unit2.pas(20): There is no method in an ancestor class to be overridden "procedure create of Object"

When removing this override, it indeed does not compile because of passing a TJSPromise instead of a TProc. Change the declaration therefore to

type
  TOtherForm = class(TObject)
      MyProcedure:TProc;
      constructor create(ProcPoint:TJSPromise);
end;

Hi Bruno,

Thanks for the reply.

Yes, sorry I made a typo in that example! Shouldn't have put the override there.

However, in my actual code, I have formatted things correctly and the compile error is the one I've mentioned previously.

Is my initial point correct that it's no longer possible to pass an [async] TProc and we now have to declare the argument as a TJSPromise?

If that is the case, I did this already as per my example, but the TJSPromise simply runs when I assign it in the created class.

Thanks!

Can you please isolate this and provide a sample source project with which we can reproduce this?

1 Like

Of course!

unit Unit1;

interface

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

type
  TOtherClass=class(TObject)
    private
      ProcPoint:TJSPromise;
    public
      constructor create(ProcPoint:TJSPromise);
  end;

type
  TForm1 = class(TWebForm)
    WebButton1: TWebButton;
    [async] procedure WebButton1Click(Sender: TObject);
  private
    OtherClass:TOtherClass;
  private
    { Private declarations }
    [async] Procedure MyProcedure;
  public
    { Public declarations }
  end;

implementation

{$R *.dfm}

constructor TOtherClass.create(ProcPoint: TJSPromise);
begin
  Self.ProcPoint:=ProcPoint;
end;

procedure TForm1.MyProcedure;
begin
  writeln('FIRED');
end;

procedure TForm1.WebButton1Click(Sender: TObject);
begin
  OtherClass:=TOtherClass.create(MyProcedure);
end;

end.

I hope the above demonstrates my question.
As soon as the object is created and the promise is assigned to a variable, the promise resolves.

Here is the corrected project:
Project3.zip (9.2 KB)

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