【问题标题】:Stop deferred ajax calls停止延迟的 ajax 调用
【发布时间】:2015-07-20 13:44:59
【问题描述】:

我有一个函数可以从数据库中获取一些信息并使用 PHP 执行一些逻辑,这使得这个过程对于数据库中的每个结果都需要 5 到 10 秒 - 有时整个过程需要 5 分钟总计。

我知道所有进程何时完成的唯一方法是使用 jQuery 延迟调用,因为它都是异步运行的,但有时用户可能希望停止此进程并使用不同的参数重新开始。

我已经搜索了如何停止这些调用但找不到任何东西,我阅读了有关 $deferObj.reject() 的信息,但它对我不起作用,我得到 $deferObj.reject 不是函数强>

基本上我想要做的就是启动进程,当我点击 Stop 按钮时,延迟调用会停止。现在这还没有发生,我要离开那里甚至刷新重新开始,在其余的延迟调用完成时需要一些时间。

这是我启动延迟调用的代码:

    var getBooks = function( title ) {
        return $.ajax({
            url: 'ajax-handler.php',
            data: {action: 'get_books', title: title, params: $( '#params' ).val()},
            method: 'POST',
            dataType: 'json',
            success: function( results ) {
                if ( results.error ) {
                    console.log( 'Got an error processing ' + title );
                }
            }
        });
    }

    var books = new Array( 'Book 1', 'Book 2', 'Book 3', 'Book4' );
    var defBooks = new Array();
    for ( var i = 0; i < books.length; i++ ) {
        defBooks.push( getBooks( books[ i ] ) );
    }

    deferBooks = $.when.apply( $, defBooks );
    deferBooks.done( function() {
        alert( 'Process finished correctly' );
    }).fail( function () {
        alert( 'Process failed' );
    });

这段代码运行良好,当我遇到网络问题或我的 PHP 代码出现问题时,我只会收到 Process failed 消息,因此后端需要完成的所有事情都已完成.

现在,我还有一个停止进程按钮,它应该停止所有执行并让我重新开始,这是该按钮的点击事件的代码:

$( document ).on( 'click', '#stop-button', function() {
    deferBooks.reject(); // this one gives me the **deferBooks.reject is not a function** error message in the console
});

请注意,我尝试在脚本文件的最顶部声明​​ deferBooks 变量,以便它在所有函数中都可用,这就是为什么我没有收到 deferBooks is undefined 消息。

我没有想法,这是我第一次使用延迟调用,所以我可能会遗漏一些明显的东西......

谁能给我一些指导?

谢谢

【问题讨论】:

  • 一旦 AJAX 请求被发送,您无法阻止它被处理。最接近的比喻就像子弹发射后试图阻止它。
  • 好的,这意味着defBooks.push(getBooks(books[i]))中的所有函数调用;当我单击停止按钮时是否已经在运行?我应该为此使用同步调用更好吗?
  • 实际上现在我想起来很明显......我存储在我的 defBooks 数组中的是该函数为每本书返回的任何内容,这意味着所有函数都已经在运行.. ..
  • 好的,所以,如果我选择同步选项,这将意味着代码将卡在 defBooks.push( getBooks( books[ i ] ) );直到每个人都结束...然后没有太多选择...知道我可以做些什么来实现“停止”按钮吗?
  • 不,永远不要对任何事情使用同步调用。他们是非常糟糕的做法。至于停止按钮,您实际上无能为力。您可以重新启用在请求运行时禁用的任何按钮,但服务器仍将处理请求。 UI 根本不会在返回时监听。

标签: jquery jquery-deferred deferred


【解决方案1】:

一旦发送 AJAX 请求,您就无法阻止它被处理。最接近的比喻就像子弹发射后试图阻止它。

我应该为此使用同步调用更好吗?

不,永远不要对任何事情使用同步调用。他们是非常糟糕的做法。至于停止按钮,您实际上无能为力。您可以重新启用在请求运行时禁用的任何按钮,但服务器仍将处理请求。 UI 根本不会在返回时监听它。

【讨论】:

    【解决方案2】:

    jQuery ajax 调用返回一个组合 promise 和 jQuery ajax 对象。除了 promise 方法,它还有一个 .abort() 方法。这将“取消” ajax 调用并导致 promise 被拒绝。

    取消已经发送到服务器的 ajax 调用实际上可能不会对您的服务器产生任何影响,因为该请求可能已经在服务器上进行(详细信息取决于您的服务器实现以及实际请求的数量正在进行中)。但是,它确实会阻止您的成功处理程序处理结果。

    由于您在 defBooks 中拥有所有 jQuery ajax 对象,您可以这样做:

    // to cancel, you could do this:
    defBooks.forEach(function(item) {
        item.abort();
    });
    

    相关答案:

    Abort Ajax requests using jQuery

    How to cancel/abort jQuery AJAX request?


    如果您想对服务器上的取消进行更细粒度的控制,那么您必须更改发送 ajax 调用的方式,以免一次发送所有调用。相反,您将一个接一个地对它们进行排序。然后,您可以中止当前正在播放的 ajax 调用,然后不会发送其他调用。

    【讨论】:

    • @andrux - 这回答了你的问题吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 2021-10-22
    • 2014-03-15
    • 1970-01-01
    相关资源
    最近更新 更多