2014-12-12 6 views
3

Я пытаюсь использовать отложенные jQuery AJAX для возврата строки JSON, которая может быть проанализирована и использована, но я закодировал себя в углу и, возможно, прикрутил логику. Я ожидал, что результаты вызова AJAX будут возвращены в обратном вызове .done(), и они будут. Я однажды подумал, что могу вернуть результат для использования в оставшейся части функции. Я знаю, что мне не хватает чего-то действительно очевидного и простого, я просто не могу сказать, что это такое.Я использую .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 не получает переправляется последующее, если заявление, как userRole первоначально жестко закодированы для первоначального тестирования перед пытаться сделать функцию более динамичный.

Как мне вернуть foo.responseText или bar для использования в следующей процедуре? Нужно ли вводить процедуру, начиная с if условно в функции .done()?

+2

Upvote для допуска, что вы «неправильно использовать его и не говорить, что он не работает так, как должно быть» – SeinopSys

+0

Не знаю, почему мое закрытое голосование было удалено, но это дубликат: http: // stackoverflow.ком/вопросы/14220321/как к возвратным-ответ-с-с-АЯКС-вызова –

ответ

2

Вы ищете .then, а не .done.

.done выполняет действия и возвращает то же самое обещание. С другой стороны, then возвращает новое обещание, которое разрешено с возвращаемым значением обратного вызова, предоставленного ему. (Предполагая, что $.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, которые обещают подключить на него позже.

1

Похоже, вы используете синхронно отложенные объекты, которые (как вы упомянули в своем названии) не предназначены для целей. Код, обрабатывающий данные пользователя после .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();