5

如果我要从一个函数(全部用 Java 编写)调用:

public int hello() {
int a = 1;
executeCallback();
// C: Question lies in this range
return a;
}

public void executeCallback() {
// A: random code to execute before asynccallback
   randomClass.randomMethod(int a, int b, AsyncCallback<ReturnType>() {
      onSuccess();
      onFailure();
   });
// B: random code to execute after asynccallback
}

我知道注释 A 中的内容将执行,同时非同步 randomMethod 将执行,B 中的注释将执行。

不过,我想知道,当 randomMethod 正在执行时(如果它需要足够长的时间),该函数是否会返回到它的调用者(在本例中是方法“hello”)并开始执行注释 C 中的代码?还是 executeCallback 会等待 randomMethod 完成后再返回?

如果是前者,假设我需要在我可以继续评论 C 之前触摸 randomMethod 所触及的信息,我怎样才能让它“等待”以确保会是这种情况?

4

3 回答 3

3

当调用异步方法时,程序不会等待该方法,这就是它们被称为异步的原因。randomMethod AsyncCallback onSuccess 或 OnFailure 方法无法在 B. 表示的代码之前执行。因为浏览器在单个线程中执行 javascript 代码,onSuccess 或 OnFailure 方法在 executeCallBack 方法的调用者完成后执行。

如果希望代码 B 和代码 C 在 randomMethod 之后执行,则应将它们放在 onSuccess 方法中,例如;

randomClass.randomMethod(int a, int b, AsyncCallback<ReturnType>() {
      onSuccess() {
         // B: random code to execute after asynccallback
        // C: Question lies in this range
        }
      }
      onFailure()
   });
于 2011-02-17T08:09:50.203 回答
2

让我稍微解释一下执行模型,因为如果您知道“幕后”发生了什么,有时会更容易。

所有代码执行都是由浏览器发起的。这发生在某些事件中,例如当页面加载时,当用户点击某些东西时,或者当 AJAX 响应到达时。

因此,当您编写 GWT(或其他 JavaScript)应用程序时,您要做的就是注册处理程序,例如,通过使用onModuleLoad(),或通过将 ClickHandler 注册到 Button,或将 AsyncCallback 注册到 GWT-RPC 调用。

有趣的(也许是反直觉的?)的事情是,当浏览器调用这样的处理程序时,它会一直执行直到它完成(或直到发生错误)。只有在那之后,才会执行其他处理程序。顺便说一句,这也意味着,如果一个处理程序的代码包含无限循环,则永远不会执行其他回调 - 整个浏览器选项卡将阻塞。

因此,当您的hello()方法被执行时,这是作为某些处理程序的一部分完成的(例如 onModuleLoad 或 ClickHandler)。它

  • a = 1
  • 然后发送一个 AJAX 请求(randomClass.randomMethod),
  • 注册另一个AsyncCallback处理程序(请记住,这只是一个注册。浏览器将首先完成当前处理程序,然后才能实际执行该 AsyncCallback 处理程序)。
  • 执行 B
  • 执行 A
  • 继续执行调用层次结构,直到处理程序完成。
于 2011-02-17T08:39:01.607 回答
1

1]异步通信可能需要一点时间来适应。您需要记住,无论在服务器上执行过程以及从服务器到客户端的数据传输需要多长时间,客户端都会在调用远程过程之后继续执行下一条语句。

2] 你可以执行 // C: 问题在onSuccess方法的这个范围内

于 2011-02-17T08:36:44.173 回答