Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Delphi中编写Debounce()过程?_Delphi_Anonymous Methods - Fatal编程技术网

如何在Delphi中编写Debounce()过程?

如何在Delphi中编写Debounce()过程?,delphi,anonymous-methods,Delphi,Anonymous Methods,我想编写一个类似于Javascript中常用实现的去盎司过程。例如, 我想可能是这样的: procedure Debounce(const TimeMS : integer; MyAnonymousProcedure : TProc); function Debounce(Delay: TDateTime; Proc: TProc): TProc; var LastCall: TDateTime; begin LastCall := 0; Result := procedure

我想编写一个类似于Javascript中常用实现的去盎司过程。例如,

我想可能是这样的:

procedure Debounce(const TimeMS : integer; MyAnonymousProcedure : TProc);
function Debounce(Delay: TDateTime; Proc: TProc): TProc;
var
  LastCall: TDateTime;
begin
  LastCall := 0;
  Result := procedure
  begin
    if LastCall + Delay <= Now then
      Proc;
    LastCall := Now;
  end;
end;
可以像这样使用:

begin
  Debounce(200, procedure
  begin
    //Do something here...
  end);
end;
可能的实施#1

Debounce()过程将检查调用目标方法以来的时间。如果在X时间内调用了目标方法,则该方法调用将被延迟

伪代码版本:

procedure Debounce(const TimeMS : integer; MyAnonymousProcedure : TProc);
var
  TimeSinceCalled : integer;
begin
  TimeSinceCalled := FindTimeSinceProcedureLastCalled(MyAnonymousProcedure);
  if TimeMS < TimeSinceCalled then
  begin
    // The procedure hasn't been called recently,
    SaveTimeOfProcedureCall(MyAnonymousProcedure); // so save the current time...
    MyAnonymousProcedure;                          //  ...and call the procedure.
  end else
  begin
    // The procedure has been called recently so we use a timer
    // to call the procedure in X milliseconds.
    // The timer is reset each time Debounce() is called
    // so procedures will only be called when the Debounce time-out has
    // be passed.
    GlobalTimer.Reset;
    GlobalTimer.CallProcedureIn(MyAnonymousProcedure, TimeMS);
  end;
end;
procedure-Debounce(const-TimeMS:integer;MyAnonymousProcedure:TProc);
变量
调用时间:整数;
开始
TimeSinceCalled:=FindTimesinceProceducedRelastCalled(MyAnonymousProcedure);
如果调用TimeMS
我面临的问题是我需要一些方法来确定目标程序。我的第一个想法是使用目标过程的方法地址作为ID。例如:
ID:=地址(Foo)
ID:=Addr(Foo)

但这不适用于匿名方法,因为它们在我的测试中使用相同的地址。理想情况下,应该自动生成ID。有什么想法吗

您说所有匿名过程的地址都是相同的,但这是不可能的。相反,我怀疑您尝试了错误的值。你说你调用
地址
,但是没有这样的功能。您可能指的是
Addr
,它与
@
运算符相同。但是,这将为您提供
MyAnonymousProcedure
形式参数的地址,而不是其中存储的地址。很可能每次调用函数时,参数都有相同的地址

您正在寻找一种识别不同过程引用的方法。引用本身就足够了。您可以使用
t字典
将过程映射到它们的上次调用时间

危险在于,每次运行时,使用过程文字调用
Debounce
函数时,可能最终构造该过程对象的全新实例,因此其地址将不同于以前构造的任何过程,即使它使用相同的代码和相同的捕获变量值

JavaScript版本也容易出现同样的问题,这就是为什么它根本不尝试识别函数的原因。相反,它返回一个新函数,该函数封装传入的函数。新函数添加了延迟行为。在Delphi中,它可以像这样工作:

procedure Debounce(const TimeMS : integer; MyAnonymousProcedure : TProc);
function Debounce(Delay: TDateTime; Proc: TProc): TProc;
var
  LastCall: TDateTime;
begin
  LastCall := 0;
  Result := procedure
  begin
    if LastCall + Delay <= Now then
      Proc;
    LastCall := Now;
  end;
end;
函数去抖动(延迟:TDateTime;过程:TProc):TProc;
变量
LastCall:TDateTime;
开始
上次调用:=0;
结果:=程序
开始

如果LastCall+Delay我尝试使用
TDictionary
,但是
Dictionary.Contains(aProc)
函数在看起来不应该返回false时总是返回false。我用一个整数作为字典键测试了我的代码,它工作得很好,所以我不确定那里发生了什么。如果不使用Addr()或@functions,我如何获得
MyAnonymousProcedure
引用的例程的地址?我喜欢你的Debounce()实现。它非常简洁。然而,我希望避免在调用位置维护对某个例程的非公告版本的引用。因此,尝试根据匿名方法输入自动创建某种类型的ID。正如我所说的,每次使用过程文本调用函数时(即编写
procedure begin…end
),都会使用新标识创建一个新过程,因此字典正确地报告尚未看到该实例。将引用存储在变量中,然后测试变量是否存在。您将其与JavaScript进行比较,并且在该语言中,您需要存储
debounce
函数的结果;在德尔福也不会有什么不同。