Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 包装jQuery.ajax:将内部jqXHR级联为新的差异化对象以返回_Javascript_Jquery_Ajax_Promise_Jquery Deferred - Fatal编程技术网

Javascript 包装jQuery.ajax:将内部jqXHR级联为新的差异化对象以返回

Javascript 包装jQuery.ajax:将内部jqXHR级联为新的差异化对象以返回,javascript,jquery,ajax,promise,jquery-deferred,Javascript,Jquery,Ajax,Promise,Jquery Deferred,我现在正在开发jQuery插件,我想在$之前进行一些预处理操作。ajax发送: // The signature is the same with $.ajax $.myAjax = function(url, options) { var data = options.data; var promises = []; for(var name in data) { if(data.hasOwnProerty(name)) {

我现在正在开发jQuery插件,我想在
$之前进行一些预处理操作。ajax
发送:

// The signature is the same with $.ajax
$.myAjax = function(url, options) {


    var data = options.data;
    var promises = [];

    for(var name in data) {
        if(data.hasOwnProerty(name)) {
            var val = data[name];
            if(val instanceof File) {

                // I want to do some async pre-process here.
                var dfd = $.Deferred();

                var reader = new FileReader();
                reader.onload = function(e) {
                    data.name = e.target.result;
                    dfd.resolve();
                }
                reader.readAsText(val);

                promises.push(dfd.promise());
            }
        }
    }

    var deferred = $.Deferred();

    $.when.apply($, promises).done(function() {
        // In fact, I want to return, or wrap cascading this jqXHR
        //   in the outer function `$.myAjax`.
        var jqXHR = $.ajax(url, options).done(function(...) {
            // ??? If I want deferred to be a jqXHR like object, 
            // how to wrap the arguments here?
            deferred.resolve(/* Help to fill */); 
        }).fail(function(...) {
            deferred.reject(/* Help to fill */);
        });
    });

    // ** ATTENTION **
    // Here, I want to return a jqXHR compatible promise.
    // That is what I ask here.
    return deferred.promise();

}
我想在
myAjax
中返回一个延迟对象,或者更准确地说,返回一个jqXHR对象

因此,我可以使用标准的
$调用完全相同的接口。ajax
方法:

$.fn.myAjax({...}).done(function(data, textStatus, jqXHR) {
    // ...
}).fail(function(jqXHR, textStatus, errorThrown) {
    // ...
}) 
// .always ... etc.

如果我正确理解你想做什么,那就做不到。问题是,您的代码在创建jqXHR对象之前就从
$.myAjax()
返回,因此jqXHR对象不可能是
$.myAjax()
函数调用的实际返回对象。您可以从返回的承诺中访问它,但是返回的承诺将是在ajax调用开始之前创建的承诺

仅供参考,当您从
$.when()
处理程序返回
$.ajax()
时,您的代码中也有一些promise反模式,而不是使用您创建的另一个延迟模式。从
处理程序中返回承诺。然后()
处理程序会自动将该承诺链接到原始承诺


这是您发布的解决方案的清理版本。更改摘要:

  • 将文件读取封装到本地函数中,以避免在循环中声明函数,并允许所有核心逻辑流仅使用承诺,而不是承诺和回调的混合(例如,封装回调)
  • 向文件读取器添加了错误处理
  • 将延迟切换到回调模型(std承诺使用)
  • 删除并返回ajax承诺,whcih将根据需要从ajax调用中提供解析或拒绝的参数
  • 切换到
    .then()
    ,它具有更标准的行为,并且在jQuery使其承诺符合标准时无需更改
  • 守则:

    // The signature is the same with $.ajax
    $.myAjax = function(url, options) {
    
        function readFile(data, name) {
            var file = data[name];
            if (file instanceof File) {
                return $.Deferred(function(dfd) {
                    var reader = new FileReader();
                    reader.onload = function(e) {
                        dfd.resolve(e.target.result);
                        data[name] = e.target.result;
                    };
                    reader.onerror = reader.onabort = dfd.reject;
                    reader.readAsText(file);
    
                }).promise();
            }
        }
    
        var data = options.data;
        var promises = [];
    
        for(var name in data) {
            if(data.hasOwnProerty(name)) {
                promises.push(readFile(data, name));
            }
        }
    
        // trigger when all file fields was loaded.
        // so the data were all constructed.
        return $.when.apply($, promises).then(function() {
            return $.ajax(url, options);
        });
    }
    

    如果我正确理解你想做什么,那就做不到。问题是,您的代码在创建jqXHR对象之前就从
    $.myAjax()
    返回,因此jqXHR对象不可能是
    $.myAjax()
    函数调用的实际返回对象。您可以从返回的承诺中访问它,但是返回的承诺将是在ajax调用开始之前创建的承诺

    仅供参考,当您从
    $.when()
    处理程序返回
    $.ajax()
    时,您的代码中也有一些promise反模式,而不是使用您创建的另一个延迟模式。从
    处理程序中返回承诺。然后()
    处理程序会自动将该承诺链接到原始承诺


    这是您发布的解决方案的清理版本。更改摘要:

  • 将文件读取封装到本地函数中,以避免在循环中声明函数,并允许所有核心逻辑流仅使用承诺,而不是承诺和回调的混合(例如,封装回调)
  • 向文件读取器添加了错误处理
  • 将延迟切换到回调模型(std承诺使用)
  • 删除并返回ajax承诺,whcih将根据需要从ajax调用中提供解析或拒绝的参数
  • 切换到
    .then()
    ,它具有更标准的行为,并且在jQuery使其承诺符合标准时无需更改
  • 守则:

    // The signature is the same with $.ajax
    $.myAjax = function(url, options) {
    
        function readFile(data, name) {
            var file = data[name];
            if (file instanceof File) {
                return $.Deferred(function(dfd) {
                    var reader = new FileReader();
                    reader.onload = function(e) {
                        dfd.resolve(e.target.result);
                        data[name] = e.target.result;
                    };
                    reader.onerror = reader.onabort = dfd.reject;
                    reader.readAsText(file);
    
                }).promise();
            }
        }
    
        var data = options.data;
        var promises = [];
    
        for(var name in data) {
            if(data.hasOwnProerty(name)) {
                promises.push(readFile(data, name));
            }
        }
    
        // trigger when all file fields was loaded.
        // so the data were all constructed.
        return $.when.apply($, promises).then(function() {
            return $.ajax(url, options);
        });
    }
    

    如果我正确理解你想做什么,那就做不到。问题是,您的代码在创建jqXHR对象之前就从
    $.myAjax()
    返回,因此jqXHR对象不可能是
    $.myAjax()
    函数调用的实际返回对象。您可以从返回的承诺中访问它,但是返回的承诺将是在ajax调用开始之前创建的承诺

    仅供参考,当您从
    $.when()
    处理程序返回
    $.ajax()
    时,您的代码中也有一些promise反模式,而不是使用您创建的另一个延迟模式。从
    处理程序中返回承诺。然后()
    处理程序会自动将该承诺链接到原始承诺


    这是您发布的解决方案的清理版本。更改摘要:

  • 将文件读取封装到本地函数中,以避免在循环中声明函数,并允许所有核心逻辑流仅使用承诺,而不是承诺和回调的混合(例如,封装回调)
  • 向文件读取器添加了错误处理
  • 将延迟切换到回调模型(std承诺使用)
  • 删除并返回ajax承诺,whcih将根据需要从ajax调用中提供解析或拒绝的参数
  • 切换到
    .then()
    ,它具有更标准的行为,并且在jQuery使其承诺符合标准时无需更改
  • 守则:

    // The signature is the same with $.ajax
    $.myAjax = function(url, options) {
    
        function readFile(data, name) {
            var file = data[name];
            if (file instanceof File) {
                return $.Deferred(function(dfd) {
                    var reader = new FileReader();
                    reader.onload = function(e) {
                        dfd.resolve(e.target.result);
                        data[name] = e.target.result;
                    };
                    reader.onerror = reader.onabort = dfd.reject;
                    reader.readAsText(file);
    
                }).promise();
            }
        }
    
        var data = options.data;
        var promises = [];
    
        for(var name in data) {
            if(data.hasOwnProerty(name)) {
                promises.push(readFile(data, name));
            }
        }
    
        // trigger when all file fields was loaded.
        // so the data were all constructed.
        return $.when.apply($, promises).then(function() {
            return $.ajax(url, options);
        });
    }
    

    如果我正确理解你想做什么,那就做不到。问题是,您的代码在创建jqXHR对象之前就从
    $.myAjax()
    返回,因此jqXHR对象不可能是
    $.myAjax()
    函数调用的实际返回对象。您可以从返回的承诺中访问它,但是返回的承诺将是在ajax调用开始之前创建的承诺

    仅供参考,当您从
    $.when()
    处理程序返回
    $.ajax()
    时,您的代码中也有一些promise反模式,而不是使用您创建的另一个延迟模式。从
    处理程序中返回承诺。然后()
    处理程序会自动将该承诺链接到原始承诺


    这是您发布的解决方案的清理版本。更改摘要:

  • 将文件读取封装到本地函数t中
    var dfd = $.myAjax({
        url: '...',
        // ...
    }).done(function(data, textStatus, jqXHR) {
        // triggered when the inner ajax done ...
    }).fail(function(jqXHR, textStatus, errorThrown) {
        // triggered when the inner ajax fail ...
    });