【问题标题】:I'm using .done() incorrectly, doesn't return value as expected我使用 .done() 不正确,没有按预期返回值
【发布时间】:2015-02-11 14:03:16
【问题描述】:

我正在尝试使用 jQuery 的 AJAX deferreds 来返回一个可以解析和使用的 JSON 字符串,但我已经将自己编码到一个角落并且可能搞砸了逻辑。我希望 AJAX 调用的结果会在 .done() 回调中返回,它们是。我认为一旦完成,我可以返回结果以用于函数的其余部分。我知道我遗漏了一些非常明显和简单的东西,我无法确定它是什么。

这是函数的初始编码,仍然非常处于测试模式。 JSON 在.done() 函数中正确返回,但我无法将其分配到函数之外以供使用。

checkUserRoles = function(){
    var userRole, foo, roles, i$, len$, i;
    userRole = roleChecker();
    foo = userRole.done(function(data){
        var bar;
        bar = foo.responseText; // correctly returns the JSON data
        console.log(bar);
        return bar; //  is undefined, this is the problem
    });
    if (userRole !== false) {
        userRole = jsonDecode(userRole);
    } else {
        userRole = "";
    }
    roles = userRole.split(',');
    $("if-user-role").hide();
    for (i$ = 0, len$ = roles.length; i$ < len$; ++i$) {
        i = roles[i$];
        $("if-user-role[data-role~=" + i + "]").show();
    }
    return true;
};
this.roleChecker = function(){
    var retVal, allCookies, i$, len$, thecookie, hashedCookie, theHash, userHash, post;
    retVal = "";
    allCookies = document.cookie.split(';');
    for (i$ = 0, len$ = allCookies.length; i$ < len$; ++i$) {
        thecookie = allCookies[i$];
        if (thecookie.indexOf('userHash') >= 0) {
            hashedCookie = thecookie;
            theHash = hashedCookie.split('=');
            userHash = theHash[1];
        }
    }
    post = $.ajax({
        url: '/services/check_hash.php',
        data: {
            hash: userHash
        },
        type: "POST"
    });
    return post;
};

您在此处看到的代码是我们广泛使用的 LiveScript 编译的输出。我不认为 LiveScript 对最终结果有影响,我只需要做很多事情才能得到我期望的正确的 JavaScript / jQuery 输出。

注意:因为这或多或少是代码 foo 的第一次传递,因此不会传递到后续 if 语句,因为 userRole 最初是硬编码的在尝试使函数更具动态性之前进行测试。

如何返回foo.responseText 或bar 以供后续程序使用?我是否需要在.done() 函数中以if 条件开头的过程?

【问题讨论】:

标签: javascript jquery promise deferred


【解决方案1】:

您正在寻找.then,而不是.done。

.done 所做的是执行一个操作并返回相同的承诺。另一方面,then 返回一个新的 Promise,它通过提供给它的回调的返回值来解决。 (假设$.ajax 正确解析)。

你当然需要把你随后做的所有事情都放在链中:

userRole.then(function(data){
    var bar;
    bar = foo.responseText; // correctly returns the JSON data
    console.log(bar);
    return bar;
}).then(function(role){;
  if (role != false) {
    role = jsonDecode(userRole);
  } else {
    userRole = "";
  }
//...
  return true;
});

您还应该return 承诺稍后再联系它。

【讨论】:

    【解决方案2】:

    看起来您正在同步使用延迟对象,这(正如您在标题中提到的)不是预期的目的。在.done() 之后处理用户数据的代码将在注册该处理程序后立即执行,因此您的数据还没有准备好。

    当您在延迟承诺上注册.then() 时,您是在告诉您的程序在延迟对象已解决或被拒绝后运行一段代码。程序不会等待直到延迟对象解决或拒绝,它会继续处理代码(这是延迟对象系统的美妙之处!)

    例子:

    var checkUserRoles = function () {
        var userRole = roleChecker();
    
        // go off and find the user data
        // but *don't wait for it before continuing code execution*
        userRole.then(function(data){
    
          // at this point the AJAX request has finished, and we have the data
          console.log(data);
    
          // put code to process the user data here
        });
    
        // code here is executed immediately after registering the .then handler
        // so the user data has not loaded yet
    };
    
    var roleChecker = function () {
        var defer = $.Deferred();
        var post = defer.promise();
    
        // simulate an AJAX Request, returns after 2 seconds
        setTimeout(function () {
          defer.resolve('user data here!');   
        }, 2000);
    
        return post;
    };
    
    checkUserRoles();
    

    【讨论】:

      猜你喜欢
      • 2016-10-22
      • 1970-01-01
      • 2018-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多