有人可以解释回调/事件触发

Ank*_*kur 1 events web-applications callback

在之前的SO问题中,建议我使用回调/事件触发而不是轮询.有人可以更详细地解释这一点,或许可以参考在线教程,这些教程展示了如何为基于Java的Web应用程序做到这一点.

谢谢.

Mic*_*cah 12

维基百科回调的定义是:

在计算机编程中,回调是可执行代码,作为参数传递给其他代码.它允许较低级别的软件层调用更高级别层中定义的子例程(或函数).

在它的基本形式中,可以像这样使用回调(伪代码):

void function Foo()
{
   MessageBox.Show("Operation Complete");
}

void function Bar(Method myCallback)
{
  //Perform some operation
  //When completed execute the callback method
  myCallBack().Invoke();
}

static int Main()
{
   Bar(Foo); //Pops a message box when Bar is completed
}
Run Code Online (Sandbox Code Playgroud)

像Java和c#这样的现代语言有一种标准化的方法,它们称之为事件.事件只是一个特殊类型的属性添加到一个类,其中包含一个Delegates/Method Pointers/Callbacks列表(这三个事情都是相同的.当事件被"触发"时,它只是迭代它的回调列表并执行它们.这些也称为监听器.

这是一个例子

public class Button
{
   public event Clicked;

   void override OnMouseUp()
   {
        //User has clicked on the button. Let's notify anyone listening to this event.
       Clicked(); //Iterates through all the callbacks in it's list and calls Invoke();
   }
}

public class MyForm
{
   private _Button;

   public Constructor()
   {
       _Button = new Button();

      //Different languages provide different ways of registering listeners to events.
      // _Button.Clicked += Button_Clicked_Handler;
      // _Button.Clicked.AddListener(Button_Clicked_Handler); 
   }

   public void Button_Clicked_Handler()
   {
       MessageBox.Show("Button Was Clicked");
   }
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,Button类具有一个名为Clicked的事件.它允许任何想要在被点击时收到通知的人注册回调方法.在这种情况下,"Button_Clicked_Handler"方法将由Clicked事件执行.

每当您需要通知程序中其他地方发生了某些事情并且您不知道何时或如何发生这种情况时,事件/回调体系结构非常方便.

这大大简化了通知.轮询使其变得更加困难,因为您有责任经常检查操作是否已完成.一个简单的轮询机制是这样的:

static void CheckIfDone()
{
    while(!Button.IsClicked)
    {
       //Sleep
    }

    //Button has been clicked.
}
Run Code Online (Sandbox Code Playgroud)

问题是这种特殊情况会阻塞你现有的线程,并且必须继续检查,直到Button.IsClicked为真.关于事件体系结构的好处是它是异步的,让代理项(按钮)在完成时通知监听器而不是监听器必须继续检查,


Art*_*ler 5

轮询和回调/事件之间的区别很简单:

  • 轮询:您连续或每隔固定时间询问是否满足某些条件,例如是否按下了某个键盘按键。
  • 回调:您对某些驱动程序、其他代码或其他内容说:当发生某些事情时(在我们的示例中按下了键盘),调用此函数,然后将事件发生时您想要调用的函数传递给它。这样,您就可以“忘记”该事件,并知道它发生时会得到正确处理。