【问题标题】:Does this deferred require a resolution of some sort这是否需要某种解决方案
【发布时间】:2013-02-26 19:28:29
【问题描述】:

在为会员或客人准备页面之前,我正在检查用户是否已登录。如果他们有 cookie,他们就是会员,如果没有,他们就是客人。

我做得对吗?

function check_if_member(){

    var dfd = new $.Deferred();
    if (readCookie('isco')){
        //adds jquery data() element "user_information"
        //after making a jquery ajax post to retrieve it
        //and using a template to write data to the page
        //with the `success()` callback
        prepare_member('member');
    } else {
        //reveals some HTML on the page
        prepare_member('guest');
    }  
}

$(document).ready(function(){
    //before page loads, check if user is member
    $.when(check_if_member())
     .then(function(){
        console.log($('body').data('user_information'));
        return false; 
     });
});

我想我终于对 deferred 有了一些了解,但它们仍然让我感到困惑,我想知道我是否已经适当地构造了这个,或者我是否需要在我的任何 ajax 请求中添加解析或返回行或将收集到的信息保存到 jquery data() 的行。谢谢。

编辑

prepare_member 函数

function prepare_member(type) {

    if (type == 'member') {
        var user_information = readCookie('isco')

        $('body').data('user_information', user_information);

        var user_id = $('body').data('user_information').user_id;

        $.ajax({
            type: 'post',
            url: "/address.php",
            data: {
                type: "retrieve",
                user_id: user_id,
                isbilling: true
            },
            dataType: 'json',
            success: function (returnedData) {

                $('body').data('user_information').billing_information = returnedData['address_0'];

                //populate member billing fields
                $('#member_billing_container').append('<div>').children(':last')
                                                              .vkTemplate('/member_billing_template.tmpl', returnedData, function () {
                                                                  //some callback - possibly resolve promise
                                                              });
                //populate member contact fields
                $('#member_contact_container').append('<div>').children(':last')
                                                              .vkTemplate('/member_contact_template.tmpl', JSON.stringify(user_information), function () {
                                                                  //some callback - possibly resolve promise  
                                                               });
            }
        });

        $('.guest_container, .guest').hide();
        $('.member_container, .member').show();

    } else {

        $('.guest_container, .guest').show();
        $('.member_container, .member').hide();

    }

}

【问题讨论】:

  • 是的,你必须解决 Deferred,否则传递给 then() 的函数将永远不会被调用。您还需要从 check_if_member() 返回 Deferred 的承诺。
  • @FrédéricHamidi 谢谢。你能告诉我这些线的确切位置吗? `在ajax成功回调中解析?
  • 如果你用prepare_member()的代码更新你的问题我可以试试:)
  • @FrédéricHamidi 当然。两秒钟。让我做一个简短的版本。
  • @FrédéricHamidi 已更新,感谢您的关注!

标签: jquery jquery-deferred


【解决方案1】:

首先,由于我们谈论的是延迟,我们不会使用success 处理程序。 $.ajax() 返回一个承诺,因此我们可以将其链接到 done() 并继续使用延迟模式。

然后,假设您想在成员数据可用时立即解决您的 Deferred(这实际上使答案变得更加简单,因为 vkTemplate() 不返回承诺,我们可能必须按顺序编写一个包装器以保持代码可读性)。

结果会是这样的:

function check_if_member()
{
    var dfd = $.Deferred(),           // Can be called without 'new'.
        cookie = readCookie("isco");  // Avoid reading cookie twice.
    prepare_member(cookie, dfd);
    return dfd.promise();             // Return promise.
}

function prepare_member(user_information, dfd) {
    if (user_information) {
        // Member mode.
        $("body").data("user-information", user_information);
        $.ajax({
            type: "post",
            url: "/address.php",
            data: {
                type: "retrieve",
                user_id: user_information.user_id,
                isbilling: true
            },
            dataType: "json"
        }).done(function(returnedData) {
            user_information.billing_information = returnedData["address_0"];
            dfd.resolve();  // Member data is available, resolve Deferred.
            $("#member_billing_container").append("<div>").children(":last")
                .vkTemplate("/member_billing_template.tmpl", returnedData,
                    function() {
                        // Maybe chain widgets or handlers...
                    });
            $("#member_contact_container").append("<div>").children(":last")
                .vkTemplate("/member_contact_template.tmpl",
                    JSON.stringify(user_information),
                    function () {
                        // Maybe chain widgets or handlers...
                    });
        });
        $(".guest_container, .guest").hide();
        $(".member_container, .member").show();

    } else {
        // Guest mode.
        dfd.resolve();  // No member data available, resolve Deferred
                        // (synchronously here). You might also want
                        // to reject() it instead.
        $(".guest_container, .guest").show();
        $(".member_container, .member").hide();
    }
}

$(document).ready(function() {
    $.when(check_if_member())
     .then(function() {
          console.log($("body").data("user-information"));
     });
});

现在,也许您不必使用&lt;body&gt; 元素的数据将用户信息传递给您的then() 处理程序。延迟对象可以连同任何信息一起解决(或拒绝或通知),例如:

user_information.billing_information = returnedData["address_0"];
dfd.resolve(user_information);  // Member data is available, resolve Deferred
                                // and pass user information through promise.

那么你只需要写:

$(document).ready(function() {
    $.when(check_if_member())
     .then(function(user_information) {
          console.log(user_information);  // Will be undefined in guest mode.
     });
});

【讨论】:

  • 这个很清楚。非常感谢。我能问一下你在编辑中做了什么改变吗?好像您删除了将data() 附加到正文的行?这是正确的吗?
  • @thomas,当然,我删除了对data() 的第二次调用,因为它没有必要。 user_information 仍然是第一次与data() 关联的对象(就在调用$.ajax() 之前),因此对其所做的更改会自动反映在“另一边”。
  • 啊哈,当然。我非常感谢你的所有帮助。在实现它时,我可能会继续问一些问题,但这非常明显很有帮助。 :)
  • 为什么要返回第6行的promise?那个的真实意义是什么?那个返回值去哪里了?
  • 我的错误。输入错误的函数名。一切都是票!再次感谢一百万!
猜你喜欢
  • 1970-01-01
  • 2016-03-31
  • 1970-01-01
  • 1970-01-01
  • 2023-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-02
相关资源
最近更新 更多