如何停止数据表实例已启动的所有当前正在进行的 Ajax 查询

How can I stop all the currently ongoing Ajax queries that DataTables instance have started?

本文关键字:正在进行 Ajax 查询 实例 数据表 启动 何停止      更新时间:2023-09-26

简要说明

将测试服务器重置

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

详细说明

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

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

    测试
  1. 运行程序启动测试服务器。

  2. 测试
  3. 运行程序在测试浏览器中加载一个页面,其中包含 DataTable 实例。

  4. 测试运行
  5. 程序运行测试,测试执行其检查并结束。

  6. 测试
  7. 运行程序将测试服务器重置为下一个测试的已知状态。

  8. 页面上会显示一条警报,指出数据表遇到 Ajax 错误。警报说:

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

  1. 我的测试系统不期望收到警报,它很困惑,即使测试实际上成功了,也会记录失败。(或者在某些情况下,它会崩溃。

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

解决方案已被拒绝

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

  • 修改测试服务器:我更喜欢保持服务器简单,而不用担心可能未得到应答的请求。

  • 等待
  • 客户端所有请求结束:这可能会大大减慢测试速度,尤其是当对数十个测试重复此等待时。

  • 将测试浏览器定向到一个新页面,上面没有 DataTables,因为这会中断当前请求:同样,这将损害测试性能。

解决方案

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

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();
    }
}

解释

编写代码即使在未加载 jQuery 或未加载 DataTable 的页面上执行时也能正常工作。因此,它首先检查它们是否已加载,如果未加载,则不执行任何操作。然后,它获取所有数据表实例的设置对象。在每个设置对象中,它检查是否存在 jqXHR ,当发出 Ajax 请求时,该对象填充了一个 jQuery jqXHR 对象。它将在其上调用 abort() 方法,从而中止请求。

上面的代码适用于数据表 1.10,

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

请注意,上面的代码不会阻止 DataTables 实例发起请求。但这不是我关心的问题。

我认为更好的方法是在DataTables中使用preXhr.dt事件。

$('.datatable').
  on('preXhr.dt', function ( e, settings, data ) {
    if (settings.jqXHR) settings.jqXHR.abort();
}).DataTables({});
我喜欢

所选的解决方案,但是当我在注入的html请求中加载数据表网格时,它不起作用。我使用 on Search 事件来触发上面提出的代码,它似乎工作正常。

myDataTable.on('search', function () {
            console.log ('Searching aborted');
            //fix to prevent datatables from crashing searches on large data sets
            if (typeof $ !== "undefined" && $.fn.dataTable) {
                let allSettings = $($.fn.dataTable.tables()).DataTable().settings();
                for (let i = 0, settings; (settings = allSettings[i]); ++i) {
                    if (settings.jqXHR)
                        settings.jqXHR.abort();
                }
            }
        });