【问题标题】:How to override the jQuery.ajax success function after it has been initialized?初始化后如何覆盖jQuery.ajax成功函数?
【发布时间】:2015-02-26 03:10:09
【问题描述】:

按钮单击触发 ajax 请求。当用户在第一个请求仍在加载时第二次单击该按钮时,我想用另一个请求覆盖第一个请求的成功函数。

基本上我想这样做:

var ajaxRequest = null;

jQuery('#mybutton').click(function () {
    if (ajaxRequest) {
        ajaxRequest.success = function () {
        };
    }

    ajaxRequest = jQuery.ajax({
        url: '...',
        success: function () {
            console.debug('do something');
        }
    });
});

但是调用了初始成功处理程序。 如何实现覆盖?

【问题讨论】:

  • 您要覆盖的用例是什么?使用您提供的代码 sn-p,第二行似乎是多余的。
  • 按钮点击触发 ajax 请求。当用户在第一个请求仍在加载时第二次单击该按钮时,我想用另一个请求覆盖第一个请求的成功函数。
  • 成功函数是做什么的?也许您可以使用一些动态 DOM 操作来代替?
  • 如何实现覆盖?...嗯,我想它不应该是必需的。但是您是否也要在其他地方使用响应数据?
  • 让我描述一下我的用例——如果我单击按钮,就会触发一个 jQuery.ajax 请求。如果您单击第二次、第三次、第四次、第五次、.. 次,当前请求(如果存在)应该得到一个空的成功处理程序( function() {} ),因此只有最后一个请求应该有正确的成功处理程序。我将更新我上面的代码来解释我的意思。

标签: javascript jquery ajax


【解决方案1】:

您可以尝试以下 hack,我已经使用 asynch setTimeout(而不是 asynch jQuery.ajax)对其进行了测试,它可以工作 -

var mySuccessHander = function() {
    console.debug('Initial function');
}

var test = jQuery.ajax({
    url: '...',
    success: function() {
        mySuccessHander();
    }
});

而当第二次点击按钮时,执行如下-

mySuccessHander = function() {
    console.debug('Overridden function');
}

【讨论】:

  • 让我描述一下我的用例——如果我单击按钮,就会触发一个 jQuery.ajax 请求。如果您单击第二次、第三次、第四次、第五次、.. 次,当前请求(如果存在)应该得到一个空的成功处理程序( function() {} ),因此只有最后一个请求应该有正确的成功处理程序。我将更新我上面的代码来解释我的意思。
  • 但是你如何预测最后一次点击呢?用户可以根据需要点击任意次数,点击一定次数后可能不会点击。
  • 当我每次点击重置最后一个 ajaxRequest 的成功处理程序时,最后一个请求自动拥有唯一正确的成功处理程序,这就是我想要做的。
  • 是的,所以每次用户点击按钮时,您都可以将 mySuccessHandler 更改为您上次分配的内容。
  • 很遗憾没有,因为所有请求都将使用新的处理程序。我只想更新当前之前的那些。在问题中查看我的代码。
【解决方案2】:

很好的问题,这会起作用..

var isRequestDone = true;

jQuery('#mybutton').click(function () {
    var requestParams = {
        url: '....',
        beforeSend: function () {
            isRequestDone = false;
        },
        success: function () {
            isRequestDone = true;
            console.debug('do something');
        },
        error: function () {
            isRequestDone = true;
        }
    }
    if (!isRequestDone) {
        requestParams.success = function () {
            console.log('please wait for a while!'); 
        };
    }

    jQuery.ajax(requestParams);
});

beforeSend 将在请求到达服务器之前触发,因此当请求在服务器上时 isRequestDone 将是错误的,因此将更改成功处理程序。在第一次请求成功回调时,它会再次回到原来的状态。

【讨论】:

  • 是的,这是个好主意。只是为了满足我的好奇心,如果我有一个当前正在进行的请求的 jQuery.ajax 对象,我不能更改它的成功处理程序或它的任何其他内容(基本上这就是我的问题所在)?
  • 看,几乎所有的 javascript 框架都提供异步行为,因为这就是 javascript 的本质(回调的东西),如果你想用你的代码实现,你应该有你可以完成的请求阻塞行为像hunlock.com/blogs/Snippets%3a_Synchronous_AJAX(也有例子。)当然你也会发现类似的JQuery......祝你好运......
  • 好吧,我的用例不是阻止用户再次点击按钮,而是之前的请求应该有另一个 ajax 处理程序。同步 AJAX 将冻结浏览器,直到请求完成,因此您不能在此期间再次单击该按钮。 (顺便说一句,它可以通过将 async: false 添加到 jQuery.ajax 选项对象来完成),并且您的示例设置了最后一个请求的成功函数 - 但我想在此之前更改请求的成功处理程序并仍然让最后一个请求有实际的成功函数。
【解决方案3】:

您可以先将 ajax 参数设置为一个变量,以便稍后对其进行修改。

var clicks = 0,
    ajaxArgs = {
        url: '...',
        success: function () {
            console.debug('do something');
        }
    };


$('#myButton').click(function() {
    ++clicks; 
    if (clicks > 1) {
        // set the success function if clicked more than once
        ajaxArgs.success = function () {
            console.debug('Success function ' + clicks);
        }
    }

    $.ajax(ajaxArgs);
});

如果您只想在 ajax 仍在加载时修改成功函数,您可以这样做:

var loading = false,
    ajaxArgs = {
        url: '...',
        success: function () {
            console.debug('do something');
        }, complete: function () {
            loading = false;
        }
    };

$('#myButton').click(function() {
    if (loading) {
        // set the success function if ajax is still loading
        ajaxArgs.success = function () {
            console.debug('Another Success function ');
        }
    } else {
        loading = true;
        $.ajax(ajaxArgs);
    }
});

【讨论】:

  • 看上面的答案——我想改变之前的请求的成功处理程序,仍然让最后一个请求具有实际的成功功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-12
  • 2020-08-23
相关资源
最近更新 更多