如何停止 DataTables 实例已启动的所有当前正在进行的 Ajax 查询? [英] How can I stop all the currently ongoing Ajax queries that DataTables instance have started?

查看:21
本文介绍了如何停止 DataTables 实例已启动的所有当前正在进行的 Ajax 查询?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简要说明

将测试服务器重置为已知状态会导致我的测试失败,因为在服务器重置时 DataTables 实例启动的 Ajax 请求正在进行中.我想通过在服务器重置之前停止 DataTables 请求来防止这种情况发生.

详细说明

我有一个应用程序,在其中我在某些页面上使用了 DataTables.这些数据表都执行服务器端查询来填充它们的表.

当我执行系统测试时,有时可能会发生竞争条件:

  1. 测试运行器启动测试服务器.

  2. 测试运行器在测试浏览器中加载一个页面,页面上有一个 DataTable 实例.

  3. 测试运行器运行测试,执行检查并结束.

  4. 测试运行器将测试服务器重置为已知状态以供下一个测试使用.

  5. 页面上出现一个警告,说 DataTables 遇到了 Ajax 错误.警报说:

<块引用>

DataTables 警告:table id=[some id] - Ajax 错误.有关此错误的详细信息,请参阅 http://datatables.net/tn/7

  1. 我的测试系统没有预料到警报,即使测试实际上是成功的,它也很困惑并记录为失败.(或者在某些情况下,它会崩溃.)

我知道这是因为服务器突然中断了 Ajax 请求.我正在寻找的是一种首先防止警报出现的方法.我想在服务器重置之前停止所有正在进行的 DataTables 请求.

解决方案已被拒绝

  • 告诉 DataTables 实例不要使用警报:如果 DataTables 实例遇到与重置测试服务器无关的问题,我希望我的测试大声失败.

  • 修改测试服务器:我更喜欢让服务器保持简单,而不用担心那里可能没有响应的请求.

  • 等待客户端完成所有请求:这会显着减慢测试速度,尤其是在数十个测试重复此等待时.

  • 将测试浏览器定向到一个新页面,上面没有数据表,因为这会中断当前的请求:同样会影响测试性能.

解决方案

解决方案

在测试完成所有检查后,让驱动浏览器的软件在浏览器中执行以下代码.(这将在测试后运行某种拆卸"代码.)

if (typeof $ !== "undefined" && $.fn.dataTable) {var all_settings = $($.fn.dataTable.tables()).DataTable().settings();for (var i = 0, settings; (settings = all_settings[i]); ++i) {如果(settings.jqXHR)settings.jqXHR.abort();}}

说明

即使在未加载 jQuery 或未加载 DataTables 的页面上执行时,代码也能正常工作.所以它首先检查它们是否被加载,如果它们没有加载则不做任何事情.然后它获取所有 DataTable 实例的设置对象.在每个设置对象中,它会检查 jqXHR 的存在,该代码填充了 jQuery 发出 Ajax 请求时的 jqXHR 对象.它将调用 abort() 方法,从而中止请求.

无论表使用 1.10 API 还是 1.9 API,上面的代码都适用于 DataTables 1.10.但是,请注意 jqXHR 字段并不是公共 API 的正式组成部分.同时,其中一位开发人员在 DataTables 论坛,因此这可能不是依赖的私有 API 中风险最大的部分.一个完全依赖公共 API 的解决方案会更加麻烦,因为必须修改所有 DataTable 实例以跟踪标记 Ajax 事务开始及其结束的事件,或者自定义 Ajax 处理程序等.这将有不仅要为正在测试的项目的代码完成,还要为任何提供碰巧使用 DataTables 的 HTML 小部件的第三方库完成.

请注意,上面的代码不会阻止 DataTables 实例发起请求.但这不是我所担心的.

Brief Description

Resetting a test server to a known state causes my tests to fail due to Ajax requests launched by DataTables instances being ongoing at the time the server is reset. I'd like to prevent this by stopping the DataTables requests before the server is reset.

Detailed Description

I have an application in which I use DataTables on some pages. These DataTables all perform server-side queries to populate their tables.

When I perform system testing, sometimes there is a race condition that can happen:

  1. The test runner starts the test server.

  2. The test runner loads in a test browser a page with a DataTable instance somewhere on it.

  3. The test runner runs the test, which performs its checks and ends.

  4. The test runner resets the test server to a known state for the next test.

  5. An alert shows up on the page, saying that DataTables experienced an Ajax error. The alert says:

DataTables warning: table id=[some id] - Ajax error. For more information about this error, please see http://datatables.net/tn/7

  1. My testing system, which is not expecting the alert, is confused and registers a failure even though the test was in fact successful. (Or in some cases, it crashes.)

I know this happens because the server abruptly interrupted an Ajax request. What I am looking for is a way to prevent the alert from coming up in the first place. I'd like to stop all ongoing DataTables requests before the server is reset.

Solutions already rejected

  • Tell the DataTables instances not to use alerts: I want my tests to fail louldly if a DataTables instance runs into an issue that is not related to resetting the test server.

  • Modifying the test server: I prefer to keep the server simple and not worry there about requests that may go unanswered.

  • Wait client-side for all requests to be over: this can slow down tests considerably, especially when this wait is repeated for dozens of tests.

  • Direct the test browser to a new page, without DataTables on it, as this will interrupt the current requests: again this will hurt test performance.

解决方案

Solution

Have the software that drives the browser execute the following code in the browser after a test has completed all its checks. (This would be in some sort of "tear down" code run after the test.)

if (typeof $ !== "undefined" && $.fn.dataTable) {
    var all_settings = $($.fn.dataTable.tables()).DataTable().settings();
    for (var i = 0, settings; (settings = all_settings[i]); ++i) {
        if (settings.jqXHR)
            settings.jqXHR.abort();
    }
}

Explanation

The code is written to work even when executed on pages that don't have jQuery loaded or don't have DataTables loaded. So it first checks whether they are loaded, and does not do anything if they are not loaded. Then it fetches the settings objects for all DataTable instances. In each settings objects, it checks for the presence of jqXHR, which is populated with a jQuery jqXHR object when an Ajax request has been made. It will call the abort() method on it, thus aborting the request.

The code above works with DataTables 1.10 whether the tables use the 1.10 API or the 1.9 API. However, note that the jqXHR field is not formally part of the public API. At the same time, one of the devs speaks about it without caveat on DataTables forum, so this is probably not the riskiest part of the private API to rely on. And a solution that relies purely on the public API would be much more cumbersome as all DataTable instances would have to be modified to track the events that mark the start of an Ajax transaction and its end or have customized Ajax handlers, etc. This would have to be done not only for the code proper to the project being tested but any 3rd party library that provides HTML widgets that happen to use DataTables.

Note that the code above does not prevent DataTables instances from initiating new requests. But this is not a concern I have.

这篇关于如何停止 DataTables 实例已启动的所有当前正在进行的 Ajax 查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆