Javascript 包装jQuery.ajax:将内部jqXHR级联为新的差异化对象以返回
我现在正在开发jQuery插件,我想在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)) {
$之前进行一些预处理操作。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反模式,而不是使用您创建的另一个延迟模式。从处理程序中返回承诺。然后()
处理程序会自动将该承诺链接到原始承诺
这是您发布的解决方案的清理版本。更改摘要:
.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反模式,而不是使用您创建的另一个延迟模式。从处理程序中返回承诺。然后()
处理程序会自动将该承诺链接到原始承诺
这是您发布的解决方案的清理版本。更改摘要:
.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反模式,而不是使用您创建的另一个延迟模式。从处理程序中返回承诺。然后()
处理程序会自动将该承诺链接到原始承诺
这是您发布的解决方案的清理版本。更改摘要:
.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反模式,而不是使用您创建的另一个延迟模式。从处理程序中返回承诺。然后()
处理程序会自动将该承诺链接到原始承诺
这是您发布的解决方案的清理版本。更改摘要:
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 ...
});