自定义 ajax promise 函数签名

Custom ajax promise function signature

我想基本上为 ajax donefail 处理程序创建一个新的函数签名...鉴于下面的简化示例,我只是想附加 resource 作为要发送给处理程序的最后一个参数。

    const customAjax = function( url, resource ) {
        const p = $.ajax({
            converters: {
                'text script': function (text: string) {
                    return text;
                }
            },
            url: url + "?" + resource
        }).then(
            function () {
                [].push.apply(arguments, [resource]);
                return arguments;
            },
            function() {
                [].push.apply(arguments, [resource]);
                return arguments;
            }
        );

        return p;
    };

那么首选用法如下:

customAjax( "url", "resourceKey" )
   .done( function( data, textStatus, jqXHR, resourceName ) { /* do something */ } )
   .fail( function( jqXHR, textStatus, errorThrown, resourceName ) { /* do something */ } );

问题是,在两个处理程序中,只有一个参数。 javascript arguments 对象。因此,要访问我真正想要的每个参数,我必须改为执行以下操作:

customAjax( "url", "resourceKey" )
   .done( function( args ) { 
      var data = args[ 0 ];
      var textStatus = args[ 1 ];
      var jqXHR = args[ 2 ];
      var resourceName = args[ 3 ];
      /* do something */
   } )
   .fail( function( args ) { 
      var jqXHR = args[ 0 ];
      var textStatus = args[ 1 ];
      var errorThrown = args[ 2 ];
      var resourceName = args[ 3 ];
      /* do something */ 
} );

有没有办法让它按照我喜欢的方式工作?

更新 - 不确定如何与关闭我的问题的人沟通,但我看不到引用的 'duplicate' 问题 answers/addresses 我的问题。

您需要覆盖 $.ajax returns 对象的 faildone 方法属性,以确保最终传递的回调然后用额外的参数调用这两个方法:

const customAjax = function( url, resource ) {
    const p = $.ajax({
        converters: {
            'text script': function (text: string) {
                return text;
            }
        },
        url: url + "?" + resource
    });
    let result = {
        ...p,
        done(f) {
            p.done(function (...args) {
                f.call(this, ...args, resource);
            });
            return result;
        },
        fail(f) {
            p.fail(function (...args) {
                f.call(this, ...args, resource);
            });
            return result;
        }
    };
    return result;
};

演示:

const customAjax = function( url, resource ) {
    const p = $.ajax({
        converters: {
            'text script': function (text) {
                return text;
            }
        },
        url: url + "?" + resource
    });
    let result = {
        ...p,
        done(f) {
            p.done(function (...args) {
                f.call(this, ...args, resource);
            });
            return result;
        },
        fail(f) {
            p.fail(function (...args) {
                f.call(this, ...args, resource);
            });
            return result;
        }
    };
    return result;
};


customAjax( "https://jsonplaceholder.typicode.com/todos/1", "resourceKey" )
    .done( function( data, textStatus, jqXHR, resourceName ) { 
        console.log( {data, textStatus, jqXHR, resourceName});
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>