Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/85.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
Jquery “Ajax承诺错误”;无法读取属性';然后';“未定义”的定义;尽管回报了承诺_Jquery_Ajax_Promise - Fatal编程技术网

Jquery “Ajax承诺错误”;无法读取属性';然后';“未定义”的定义;尽管回报了承诺

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

我试图使用一个函数通过3个ajax调用初始化数据,当这个函数完成时,我想对数据做一些事情。我必须等待3个ajax调用完成,然后才能返回承诺。问题是,如果我等待3个ajax调用完成(使用$.when(ajax1,ajax2,ajax3).done(…),我会收到未定义的错误“无法读取属性”then”

这是我的密码

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中,现在:)