我尝试使用函数初始化带有3个ajax调用的数据,当这个函数完成时,我想对数据做一些事情。在我可以返回一个承诺之前,我必须等待3个ajax调用才能完成。问题是,如果我等待3个ajax调用完成(使用$ .when(ajax1,ajax2,ajax3).done(...)),我得到错误"无法读取属性&#39 ;然后'未定义"
这是我的代码
function myInit() {
initData().then(function() {
console.log("a");
});
}
function initData() {
var results = {
categories: [],
commandes: [],
users: []
};
var ajaxCategories = $.ajax({
url: url + '/categorie/getAll',
success: function(data) {
results.categories = data;
}
});
var ajaxCommandes = $.ajax({
url: url + '/statistique/getSimpleCommandes',
success: function(data) {
results.commandes = data;
}
});
var ajaxUsers = $.ajax({
url: url + '/statistique/getSimpleUsers',
success: function(data) {
results.users = data;
}
});
$.when(ajaxUsers, ajaxCommandes, ajaxCategories)
.done(function() {
results.commandes.forEach(function(commande) {
results.users.forEach(function(user) {
if (user.id == commande.user)
commande.user = user.nom;
});
});
return $.Deferred().resolve();
});
}
我在$ .when中回复了一个承诺。如果我将此返回移动到when之外,它可以正常工作,但是我冒险退出该函数并继续使用未加载数据的代码。我的错误在哪里?
答案 0 :(得分:0)
从done
的回调中返回承诺并不会使initData
函数返回任何内容。
在$.when
调用之外创建承诺,以便您可以在回调中解析它并从initData
返回:
var promise = $.Deferred();
$.when(ajaxUsers, ajaxCommandes, ajaxCategories)
.done(function(){
results.commandes.forEach(function(commande){
results.users.forEach(function(user){
if (user.id == commande.user)
commande.user = user.nom;
});
});
promise.resolve();
});
return promise.promise();
或者,返回done
返回的承诺:
return $.when(ajaxUsers, ajaxCommandes, ajaxCategories)
.done(function(){
results.commandes.forEach(function(commande){
results.users.forEach(function(user){
if (user.id == commande.user)
commande.user = user.nom;
});
});
});
使用done
方法添加的处理程序按添加顺序调用,因此调用程序添加的任何处理程序都将在处理程序之后运行。
如果您希望在您返回的承诺中传递done
处理程序中的数据,请通过resolve
来电发送:
var promise = $.Deferred();
$.when(ajaxUsers, ajaxCommandes, ajaxCategories)
.done(function(){
results.commandes.forEach(function(commande){
results.users.forEach(function(user){
if (user.id == commande.user)
commande.user = user.nom;
});
});
promise.resolve(results);
});
return promise.promise();
答案 1 :(得分:-1)
initData()
未返回承诺,因为该函数中没有return
语句。您需要返回$.when
给您的承诺。
另外,为了链接动作并从回调中返回一些内容,您需要使用.then
而不是.done
:
function initData() {
var results = {
categories: [],
commandes: [],
users: []
};
var ajaxCategories = $.ajax({
url: url + '/categorie/getAll',
success: function(data) {
results.categories = data;
}
});
var ajaxCommandes = $.ajax({
url: url + '/statistique/getSimpleCommandes',
success: function(data) {
results.commandes = data;
}
});
var ajaxUsers = $.ajax({
url: url + '/statistique/getSimpleUsers',
success: function(data) {
results.users = data;
}
});
return $.when(ajaxUsers, ajaxCommandes, ajaxCategories)
// ^^^^^^
.then(function() {
// ^^^^
results.commandes.forEach(function(commande) {
results.users.forEach(function(user) {
if (user.id == commande.user)
commande.user = user.nom;
});
});
return results; // I guess that is what you wanted
});
}
您甚至可以通过不使用全局results
变量来进一步提升这一点,但要将其置于回调本地:
function initData() {
return $.when(
$.get(url + '/categorie/getAll'),
$.get(url + '/statistique/getSimpleCommandes'),
$.get(url + '/statistique/getSimpleUsers')
).then(function(categoriesRes, commandesRes, userRes) {
var results = {
categories: categoriesRes[0],
commandes: commandesRes[0],
users: userRes[0]
};
results.commandes.forEach(function(commande) {
results.users.forEach(function(user) {
if (user.id == commande.user)
commande.user = user.nom;
});
});
return results;
});
}