jQuery done() 向下三层
jQuery done() three levels down
我有三个 ajax 调用给我数据,我将这些数据推入数组。
第二个在第一个之后调用(在它的成功函数中),这样数组就不会被异步填充。
我的目标是在最后使用 jQuery done() 函数(或类似函数)进行某种回调(在我的代码中标记为 "END!!")。然而,jQuery done() 函数在第一级已经达到它的成功函数后开始。
var ajaxQuery = $.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {
clients:1
},
success: function(data) {
console.log("1");
for (i = 0; i < data.length; i++) {
var name = data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({name: name, usrid: data[i].usr});
}
$.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {
clients:2
},
success: function(data) {
console.log("2");
for (i = 0; i < data.length; i++) {
var name = "(CRM Lead) - " + data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({name: name, usrid: data[i].usr});
}
$.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {
clients:3
},
success: function(data) {
console.log("3");
for(i = 0; i < data.length; i++) {
var name = "(MXVV Kunden) - " + data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({name: name, usrid: data[i].usr});
}
//END!!!!!!!!
console.log(kontaktdata);
}
});
}
});
}
});
ajaxQuery.done(function(response) {alert("done");});
您可以使用延迟承诺 (http://api.jquery.com/deferred.promise):
像这样的东西应该可以工作(我没有测试过!):
var ajaxQuery = function () {
var dfd = new jQuery.Deferred();
$.ormon('ajax', {
[...]
$.ormon('ajax', {
[...]
$.ormon('ajax', {
[...]
success: function(data) {
dfd.resolve(data);
}
});
});
});
return dfd;
};
ajaxQuery().done(function (data) { [...] });
您可以在嵌套调用中调用 done()
方法:
var ajaxQuery = $.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {
clients: 1
},
success: function (data) {
console.log("1");
for (i = 0; i < data.length; i++) {
var name = data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({
name: name,
usrid: data[i].usr
});
}
$.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {
clients: 2
},
success: function (data) {
console.log("2");
for (i = 0; i < data.length; i++) {
var name = "(CRM Lead) - " + data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({
name: name,
usrid: data[i].usr
});
}
$.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {
clients: 3
},
success: function (data) {
console.log("3");
for (i = 0; i < data.length; i++) {
var name = "(MXVV Kunden) - " + data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({
name: name,
usrid: data[i].usr
});
}
//END!!!!!!!!
console.log(kontaktdata);
}
}).done(function (response) {
alert("done");
});
}
});
}
});
而不是使用 done
或 success
回调,您应该使用 then
,它 链接 异步操作并为您提供承诺最后的结果。在您的情况下,它看起来像这样:
var kontaktdata = [];
var ajaxQuery = $.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {clients: 1}
}).then(function(data) {
console.log("1");
for (var i = 0; i < data.length; i++) {
var name = data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({name: name, usrid: data[i].usr});
}
return $.ormon('ajax', {
// ^^^^^^ return another promise from the callback
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {clients: 2}
});
}).then(function(data) {
console.log("2");
for (var i = 0; i < data.length; i++) {
var name = "(CRM Lead) - " + data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({name: name, usrid: data[i].usr});
}
return $.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {clients: 3}
});
}).then(function(data) {
console.log("3");
for(var i = 0; i < data.length; i++) {
var name = "(MXVV Kunden) - " + data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({name: name, usrid: data[i].usr});
}
return kontaktdata; //END!!!!!!!!
});
ajaxQuery.done(function(result) {
console.log(result);
alert("done");
});
好的,这很好用,但看起来仍然很乏味。如果要发出的请求不止 3 个怎么办?你想在循环中对此进行编码,现在很容易实现:
var ajaxQuery = $.when([]);
for (var client=1; client<=3; client++) (function(client) {
ajaxQuery = ajaxQuery.then(function(kontaktdata) {
return $.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {clients: client}
}).then(function(data) {
console.log(client);
for (var i = 0; i < data.length; i++) {
kontaktdata.push({
name: data[i].adr1 + " " + data[i].adr2,
usrid: data[i].usr
});
return kontaktdata;
});
});
}(client)); // necessary extra scope for closure
ajaxQuery.done(function(result) {
console.log(result);
alert("done");
});
有了 promises,它会变得更好 - 您可以轻松地并行发送所有三个请求,然后 wait until they're all done,并连接结果:
var requests = [];
for (var client=1; client<=3; client++)
requests.push($.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {clients: client}
}).then(function(data) {
return data.map(function(d) {
return {name: d.adr1+" "+d.adr2, usrid: d.usr};
});
}));
var ajaxQuery = $.when.apply($, requests).then(function() {
return [].concat.apply([], arguments);
});
ajaxQuery.then(function(result) {
console.log(result);
alert("done");
}, function(err) {
console.error(err + " went wrong");
});
使用 promises 的额外好处是任何 ajax 失败或异步异常都将被捕获,您可以在最后放置一个 catch
类处理程序。
我有三个 ajax 调用给我数据,我将这些数据推入数组。
第二个在第一个之后调用(在它的成功函数中),这样数组就不会被异步填充。
我的目标是在最后使用 jQuery done() 函数(或类似函数)进行某种回调(在我的代码中标记为 "END!!")。然而,jQuery done() 函数在第一级已经达到它的成功函数后开始。
var ajaxQuery = $.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {
clients:1
},
success: function(data) {
console.log("1");
for (i = 0; i < data.length; i++) {
var name = data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({name: name, usrid: data[i].usr});
}
$.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {
clients:2
},
success: function(data) {
console.log("2");
for (i = 0; i < data.length; i++) {
var name = "(CRM Lead) - " + data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({name: name, usrid: data[i].usr});
}
$.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {
clients:3
},
success: function(data) {
console.log("3");
for(i = 0; i < data.length; i++) {
var name = "(MXVV Kunden) - " + data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({name: name, usrid: data[i].usr});
}
//END!!!!!!!!
console.log(kontaktdata);
}
});
}
});
}
});
ajaxQuery.done(function(response) {alert("done");});
您可以使用延迟承诺 (http://api.jquery.com/deferred.promise):
像这样的东西应该可以工作(我没有测试过!):
var ajaxQuery = function () {
var dfd = new jQuery.Deferred();
$.ormon('ajax', {
[...]
$.ormon('ajax', {
[...]
$.ormon('ajax', {
[...]
success: function(data) {
dfd.resolve(data);
}
});
});
});
return dfd;
};
ajaxQuery().done(function (data) { [...] });
您可以在嵌套调用中调用 done()
方法:
var ajaxQuery = $.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {
clients: 1
},
success: function (data) {
console.log("1");
for (i = 0; i < data.length; i++) {
var name = data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({
name: name,
usrid: data[i].usr
});
}
$.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {
clients: 2
},
success: function (data) {
console.log("2");
for (i = 0; i < data.length; i++) {
var name = "(CRM Lead) - " + data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({
name: name,
usrid: data[i].usr
});
}
$.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {
clients: 3
},
success: function (data) {
console.log("3");
for (i = 0; i < data.length; i++) {
var name = "(MXVV Kunden) - " + data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({
name: name,
usrid: data[i].usr
});
}
//END!!!!!!!!
console.log(kontaktdata);
}
}).done(function (response) {
alert("done");
});
}
});
}
});
而不是使用 done
或 success
回调,您应该使用 then
,它 链接 异步操作并为您提供承诺最后的结果。在您的情况下,它看起来像这样:
var kontaktdata = [];
var ajaxQuery = $.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {clients: 1}
}).then(function(data) {
console.log("1");
for (var i = 0; i < data.length; i++) {
var name = data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({name: name, usrid: data[i].usr});
}
return $.ormon('ajax', {
// ^^^^^^ return another promise from the callback
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {clients: 2}
});
}).then(function(data) {
console.log("2");
for (var i = 0; i < data.length; i++) {
var name = "(CRM Lead) - " + data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({name: name, usrid: data[i].usr});
}
return $.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {clients: 3}
});
}).then(function(data) {
console.log("3");
for(var i = 0; i < data.length; i++) {
var name = "(MXVV Kunden) - " + data[i].adr1 + " " + data[i].adr2;
kontaktdata.push({name: name, usrid: data[i].usr});
}
return kontaktdata; //END!!!!!!!!
});
ajaxQuery.done(function(result) {
console.log(result);
alert("done");
});
好的,这很好用,但看起来仍然很乏味。如果要发出的请求不止 3 个怎么办?你想在循环中对此进行编码,现在很容易实现:
var ajaxQuery = $.when([]);
for (var client=1; client<=3; client++) (function(client) {
ajaxQuery = ajaxQuery.then(function(kontaktdata) {
return $.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {clients: client}
}).then(function(data) {
console.log(client);
for (var i = 0; i < data.length; i++) {
kontaktdata.push({
name: data[i].adr1 + " " + data[i].adr2,
usrid: data[i].usr
});
return kontaktdata;
});
});
}(client)); // necessary extra scope for closure
ajaxQuery.done(function(result) {
console.log(result);
alert("done");
});
有了 promises,它会变得更好 - 您可以轻松地并行发送所有三个请求,然后 wait until they're all done,并连接结果:
var requests = [];
for (var client=1; client<=3; client++)
requests.push($.ormon('ajax', {
url: '../getjson',
trtyp: 'adm1034',
dataType: 'json',
data: {clients: client}
}).then(function(data) {
return data.map(function(d) {
return {name: d.adr1+" "+d.adr2, usrid: d.usr};
});
}));
var ajaxQuery = $.when.apply($, requests).then(function() {
return [].concat.apply([], arguments);
});
ajaxQuery.then(function(result) {
console.log(result);
alert("done");
}, function(err) {
console.error(err + " went wrong");
});
使用 promises 的额外好处是任何 ajax 失败或异步异常都将被捕获,您可以在最后放置一个 catch
类处理程序。