如何在自动调用的功能(例如.ajax()的beforeSend())上正确利用jQuery Deferred/promise? [英] How to properly utilize jQuery Deferred/promise on auto-invoked function such as .ajax()'s beforeSend()?

查看:275
本文介绍了如何在自动调用的功能(例如.ajax()的beforeSend())上正确利用jQuery Deferred/promise?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在扩展jQuery的ajaxPrefilter接口,以向AJAX调用添加其他功能;即使用beforeSend()方法中的setRequestHeader()将标头数据附加到XHR请求上.事实是,ajaxPrefilter和ajax调用本身都可以包含beforeSend选项,并且它们之一或两者都可以包含异步功能.

I'm working on extending jQuery's ajaxPrefilter interface to add additional functionality to AJAX calls; namely tacking header data onto the XHR request using setRequestHeader() within the beforeSend() method. The thing is, both the ajaxPrefilter and ajax call itself could contain beforeSend options, and one or both of them could contain async functionality.

假设我的ajaxPrefilter看起来像这样:

Assume my ajaxPrefilter looks as such:

(function($) {
    $.ajaxPrefilter(function(options, originalOptions, jqXHR) {
        var auth = $.cookie("fake_site"),
            normalizedRequest = $.Deferred();

        if (originalOptions.authorizeUser) {
            options.beforeSend = function() {
                jqXHR.setRequestHeader("Authorization", "Session " + auth);
            }

            // resolving the jqXHR Deferred, statusCode handling, etc.
        }

    });
})(jQuery);​

现在,选项原始选项都可以包含beforeSend()方法,我希望 options.beforeSend 始终先执行.这似乎是延迟/承诺用法的主要候选者,但是由于beforeSend是自动调用的,所以我不能这样做:

Now, both options and originalOptions could contain beforeSend() methods, and I want options.beforeSend to ALWAYS execute first. This would seem like a prime candidate for Deferred/promise usage, but due to the fact that beforeSend is automatically invoked, I can't do this:

options.beforeSend = function(jqXHR) {
    // setting the request header; creating, resolving, and returning the Deferred
}

$.when(options.beforeSend(jqXHR)).then(function() {
    originalOptions.beforeSend();
});

如预期的那样,这会导致options.beforeSend触发两次;都归功于其定义声明和$.when调用.

As expected, this causes options.beforeSend to fire twice; both due to its definition statement and the $.when call.

如何使用延期/承诺来管理自动调用的方法,例如beforeSend?

How would Deferreds/promises be used to manage auto-invoked methods such as beforeSend?

推荐答案

关于控制beforeSend回调后发生的情况,只有两个选项:

With regard controlling to what happens after a beforeSend callback, there are only two options :

  • 返回false以外的任何内容以允许请求继续进行,或者
  • 返回false取消请求.
  • return anything other than false to allow the request to proceed, or
  • return false to cancel the request.

您确实可以在回调中发出ajax请求,但是返回的任何内容都会导致原始(外部)ajax请求被立即发出或取消.由于回调将完成并无条件返回,因此无法通过延迟或其他方式使外部ajax依赖于内部.

You could indeed issue an ajax request within the callback but whatever is returned will cause the original (outer) ajax request to be issued issued immediately, or canceled. As the callback will complete and return unconditionally, it's not possible to make the outer ajax dependent on the inner by way of a deferred or otherwise.

要获得所需的效果,您可以在回调中以级联方式发出两个ajax请求(第二个依赖于第一个),然后返回false取消原始请求.

For the effect you want, you could, within the callback, issue two ajax requests in cascade (the second being dependent on the first) and return false to cancel the original request.

有一天,您可能想采用这种模式可能有一些晦涩的原因,但是,如果无条件地丢弃原始请求(通过返回false),那么它仅是一种复杂的方法,可以在其中实现两个ajax请求级联,不涉及beforeSend,即:

One day, there might be some obscure reason why you might want to adopt this pattern but, if the original request is discarded unconditionally (by returning false), it would be nothing more than a convoluted way of achieving two ajax requests in cascade, not involving beforeSend, ie.:

$.ajax({
    //options
}).done(function() {
    $.ajax({
        //options
    }).done(function(){
        //do stuff here
    });
});

.pipe()等价物.

总而言之,似乎不可能使jQuery ajax请求依赖于其beforeSend回调中编码的另一个异步操作,但是可以通过不涉及beforeSend的标准方式来实现所需的效果.

In summary, it appears to be impossible make a jQuery ajax request dependent on another asynchronous action coded in its beforeSend callback, however the desired effect can be achieved by standard means not involving beforeSend.

这篇关于如何在自动调用的功能(例如.ajax()的beforeSend())上正确利用jQuery Deferred/promise?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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