Jquery “Ajax承诺错误”;无法读取属性';然后';“未定义”的定义;尽管回报了承诺
我试图使用一个函数通过3个ajax调用初始化数据,当这个函数完成时,我想对数据做一些事情。我必须等待3个ajax调用完成,然后才能返回承诺。问题是,如果我等待3个ajax调用完成(使用$.when(ajax1,ajax2,ajax3).done(…),我会收到未定义的错误“无法读取属性”then” 这是我的密码Jquery “Ajax承诺错误”;无法读取属性';然后';“未定义”的定义;尽管回报了承诺,jquery,ajax,promise,Jquery,Ajax,Promise,我试图使用一个函数通过3个ajax调用初始化数据,当这个函数完成时,我想对数据做一些事情。我必须等待3个ajax调用完成,然后才能返回承诺。问题是,如果我等待3个ajax调用完成(使用$.when(ajax1,ajax2,ajax3).done(…),我会收到未定义的错误“无法读取属性”then” 这是我的密码 function myInit() { initData().then(function() { console.log("a"); }); } fun
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之外,它可以正常工作,但这样我就有可能退出函数并继续使用未加载的数据编写代码。我的错误在哪里?从
done
的回调返回承诺不会使initData
函数返回任何内容
在$之外创建承诺。当
调用时,您可以在回调中解析它,并从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();
initData()
不返回承诺,因为该函数中没有return
语句。当给你承诺时,你需要回报$
此外,要链接一个操作并从回调返回某些内容,您需要使用。然后而不是。完成:
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;
});
}
我没有在initData
-initData()
中看到任何返回
的内容。你需要使用。然后不。如果你想从回调中返回的内容,请花时间确保你的代码可读且格式合理。上述情况并非如此。编辑:不是,我已经为你修好了。谢谢,当我试图编辑它时,我真想知道为什么它已经修好了return promise代码>=>返回承诺。承诺()代码>我们不想向调用方公开完整的延迟的API。当然,$。当
已经返回承诺时。谢谢,它可以工作。我在Bergi提供的链接中读到,只有当我别无选择时才应该使用Deferred。有没有更好的方法来完成我在这段代码中要做的事情,而不直接使用$.Deferred?@Percee:你也可以使用$方法的承诺。当方法创建时,done
方法返回。我如何使用那时返回的值?我不太明白它是否返回承诺或我的结果否,您不需要使用.then
而不是.done
。在您的示例中,.then
的作用与.done
@Percee完全相同:它返回对结果的承诺-它们将作为参数用于进一步回调。例如initData.then(function(res){console.log(res.commandes);})
@Guffa:因为我从回调返回
,所以它确实有很大的不同。你可以自己试试,或者看看@Bergi:Neat,你说得对。我不必将其储存在window.data中,现在:)