javascript - Vaadin javascript 扩展中的并行 AJAX 调用

标签 javascript ajax multithreading vaadin vaadin7

我正在尝试用 javascript 编写一个简单的 Vaadin 扩展(这意味着我是 AbstractJavaScriptExtension 的子类),它会触发服务器端的方法调用。该方法调用将例如加载一些数据并更新组件的 UI。基本上,这个想法是为每个组件提供单次异步请求,目的是让服务器端可能长时间运行的数据库/Web 服务调用并行运行。

由于我不需要不断更新组件,因此使用 Vaadin Push 就有点大材小用了。我想使用普通的旧 XHR。

所以我在我的扩展类中添加了一个 javascript 触发函数,如下所示:

addFunction("trigger", jsonArray -> command.trigger());

(这是 java 8 语法,trigger() 只是功能接口(interface)上的一个方法)

我尝试在我的 javascript 连接器中立即调用此触发器,如下所示:

window.com_example_AsyncTrigger = function () {
    this.trigger();
}

我编写了一个虚拟组件,使用 Thread.sleep() 来模拟缓慢加载,并创建了三个实例,延迟分别为 10 秒、6 秒和 2 秒,同时记录加载的开始和结束时间戳。 然后,我使用扩展扩展了三个布局,以便在触发相应的触发器时将每个组件添加到其中。

当然,所有三个触发器都被触发,但它们是在同一请求中触发的(我可以从日志记录中看出它们是在单个服务器线程中执行的)。这意味着大约 18 秒后,所有 3 个组件都会同时更新,而我预计首先显示 2 秒组件,然后是 6 秒组件,最后是 10 秒组件,总时间约为 10 秒。

所以,我发现这一定是因为 Vaadin 以某种方式对创建连接包装器时完成的函数调用进行排队,并在单个请求上调用服务器端方法。因此,我更改了 javascript 连接器实现以异步调用客户端 trigger() 函数,如下所示:

window.com_example_AsyncTrigger = function () {
    var self = this;
    setTimeout(function() { self.trigger();}, 0);
}

当然,这些触发器现在在单独的请求中触发,我可以从日志记录中看出工作线程的名称是不同的。 唯一的问题是......它们仍然按顺序运行。对 self.trigger() 的调用是快速连续完成的,但实际的 XHR 请求并不是并行完成的。下一个只有在前一个完成后才会开始。

这是为什么,我该如何解决这个问题?

最佳答案

网络服务器不会并行处理来自同一客户端的请求,以防止任何竞争条件或锁定问题。要处理长时间运行的请求,您需要与处理请求的线程异步执行。完成后,使用 UI.access(...) 将结果写回 UI。处理完该请求的线程将返回并处理下一个请求。问题在于,在客户端发送下一个请求之前,结果不会发送到服务器。但所有长时间运行的请求都是并行处理的。

第一个选项:

定期轮询服务器(有一个 vaadin 插件)。结果将与下一次民意调查一起发送。

第二个选项:

不用轮询,只需使用推送。开销并没有那么大,如果您不希望同时有数百个用户,那么这应该不是问题。

进一步说明:

据我了解,Vaadin 框架是通过以下方式处理请求的:

  1. 处理从客户端发送的任何更改
  2. 调用您的监听器(ValueChange、Click...)
  3. 将更改发送给客户端

当第一个线程处于第三步时,当第二个线程更改 URL 时,这可能会导致严重的问题,因为只有一半的更改会传输到客户端。当 Vaadin 检测到告诉您使用 UI.access(...) 时,它会抛出异常。 UI.access() 负责直接执行提供的 Runnable(当没有处理其他请求时)或在当前运行的请求完成后异步执行。 最后要注意一点。锁是基于 session 的,而不仅仅是基于 UI。因此,同一 session 中不同 UI 的更改(例如同一应用程序的不同选项卡)也会按顺序处理。

关于javascript - Vaadin javascript 扩展中的并行 AJAX 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30387441/

相关文章:

javascript - jQuery.ajax - 可以为每个 ajax 请求触发两个成功回调吗?

python - Python中的线程占用过多的CPU

javascript - 如何让 javascript 随机发生器出现图像

javascript - 两个按钮可在两个功能和一个功能之间切换

javascript - AJAX:在没有页面刷新的情况下提交表单只能工作一次

java - RocksDB WriteBatch 线程安全吗?

python - 运行多个线程,直到一个线程在 python 中退出

javascript - json 对象 javascript 困惑

javascript - 下拉弹跳问题

javascript - JavaScript 和 Rails 中未定义 Uncaught ReferenceError 函数