【问题标题】:jQuery Deferred not working as expectedjQuery Deferred 没有按预期工作
【发布时间】:2015-07-07 12:39:47
【问题描述】:

这是我第一次使用$.Deferred();,事实证明这是一项使命。

我已阅读 jQuery Deferred not working,但这适用于 ajax 事件,因此对我来说并没有什么帮助。

我在 javascript 中有以下代码:

var deferred = $.Deferred();

deferred.done(function() {
    console.log(auth.loggedIn);
    if(auth.loggedIn) {
        app.page = 'usr/dashboard';
    }
}

deferred.resolve(auth.initialize());

我的auth 对象如下所示:

var auth = {

    loggedIn:false,

    initialize:function() {
        var data = {
            'login_token':app.getCookie('login_token'),
            'usr_id':app.getCookie('usr_id'),
            'source':config.source,
            'language_code':config.language_code,
            'country_code':config.country_code
        }
        app.api('usr/loggedin',data,function(data) {
            var response = JSON.parse(data);
            if(!response.result) {
                auth.loggedIn = false;
            }
            auth.loggedIn = true;
            console.log(auth.loggedIn);
        },'post');
    }
}

现在,如果我在app.api 回调中console.log(response),响应正是我所期望的,如果我console.log(auth.loggedIn) 我得到true

如果我在deferred.doneconsole.log(auth.loggedIn)console.log (在initialize 中我得到两个不同的值。我做错了什么,如何让我的应用等待auth.loggedIn 被设置?

更新

这就是我现在在我的主文件中的做法:

auth.initialize().done(function(auth) {
    if(auth.loggedIn) {
        app.page = 'usr/dashboard';
    }
    jsRouter.initialize();
});

jsRouter 基于this 20 line javascript router,现在只偶尔显示模板页面,不管我在哪个页面。

jsRouter.initialize 函数如下所示:

initialize:function() {
    window.addEventListener('hashchange',jsRouter.router);
    window.addEventListener('load',jsRouter.router);

    /* ERROR PAGES */
    jsRouter.route('404','errors/404',function() {});
    jsRouter.route('500','errors/500',function() {});

    /* ACTUAL PAGES */
    jsRouter.route('/','home',function() {});
    jsRouter.route('/home','home',function() {});
    jsRouter.route('/usr/register','usr/register',function() {});
    jsRouter.route('/usr/login','usr/login',function() {});
    jsRouter.route('/usr/forgotpassword','usr/forgotpassword',function() {});
    jsRouter.route('/usr/activate','usr/activate',function() {});
    jsRouter.route('/usr/dashboard','usr/dashboard',function() {});
    jsRouter.route('/adr','adr/index',function() {});
},

我已更新我的 app.api 回调,使其看起来与 Felix King 建议的完全一样。

【问题讨论】:

  • 我认为你在 app.api 调用中延迟了,假设它是 AJAX 调用。
  • 看来你应该 return 调用 app.api 的结果,但你不是,这会导致使用未定义的有效负载解析承诺。
  • app.api 看起来可能是异步 Javascript ......是吗?
  • app.api 是一个使用 ajax 调用 API 的函数。

标签: javascript jquery deferred


【解决方案1】:

您当前正在使用undefined 解析延迟对象,这没有意义。您还在执行 app.api 回调之前解决它。 延迟对象必须通过异步回调来解决。

auth.initialize 应该返回延迟对象/promise,你必须在app.api 回调中解决它:

var auth = {

    loggedIn:false,

    initialize:function() {
       var deferred = new $.Deferred();          // <- create deferred object
        var data = {
            'login_token':app.getCookie('login_token'),
            'usr_id':app.getCookie('usr_id'),
            'source':config.source,
            'language_code':config.language_code,
            'country_code':config.country_code
        }
        app.api('usr/loggedin',data,function(data) {
            auth.loggedIn = JSON.parse(data).result;
            deferred.resolve(auth);              // <- resolve when response was received
        },'post');
        return deferred.promise();               // <- return promise
    }
}

auth.initilize().done(function(auth) { 
  // at this point the login succeeded (or failed)
});

【讨论】:

  • 只是写了同样的答案。
  • 现在我的路由器,基于joakimbeng.eu01.aws.af.cm/a-javascript-router-in-20-lines并在if(auth.loggedIn) {}之后调用,只是有时会显示模板页面。
  • 更新了我的问题,以便在回答后更清楚
  • 这是 jQuery,因此是 return deferred.promise();(它是一个方法,而不是一个属性)。
  • @Roamer-1888:对,也已修复。没有太注意实际的逻辑。
猜你喜欢
  • 2017-06-21
  • 1970-01-01
  • 2018-03-17
  • 2019-07-13
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多