Я пытаюсь понять логику, необходимую для выполнения обещаний. Мой (упрощенный) пример:
var FLEX = FLEX || {};
FLEX.Core = {
__networkIdToken: '',
__r: "",
Init: function() {
var deferred = $.Deferred();
FLEX.Core.Config();
FLEX.Core.RegisterHandlers();
FLEX.Core.Execute();
},
Config: function() {
yam.config({
debug: true,
appId: FLEX_YAMMER_CONFIGID
});
},
RegisterHandlers: function() {
$(FLEX_YAMMER_LOGINBUTTON).on('click', function(){
FLEX.Core.Login();
});
},
Execute: function() {
//Get Network Token from local storage (if exists)
__networkIdToken = localStorage.getItem(FLEX_YAMMER_AUTHTOKEN);
if(__networkIdToken != null)
{
//If network token is set then set Auth Token and continue
yam.platform.setAuthToken(__networkIdToken);
//RETURN NEEDS TO HAPPEN HERE
}
else
{
//If no Network Token set, display login panel to enable login
FLEX.Core.ShowLoginPanel(false);
}
},
ShowLoginPanel: function (_loggedIn) {
if (_loggedIn) {
$(FLEX_YAMMER_LOGINPANEL).hide();
} else {
$(FLEX_YAMMER_LOGINPANEL).show();
}
}
}
$(document).ready(function () {
FLEX.Core.Init().done(testFunction);
function testFunction()
{
alert('Test');
}
});
Вызов из готового документа должен проверить, вошел ли пользователь в систему (выполнить функцию). Если локальный объект хранения (который устанавливает __networkIdToken) пуст, он отобразит панель входа в систему, и у нее будет независимая логика кнопки (исключена из примера). Если есть идентификатор сети, я бы хотел, чтобы обещание было возвращено здесь... удалила необходимость любой асинхронной логики для входа.
благодаря
__r = $.Deferred(); […] return __r;
__r
- свойство вашего объекта, но здесь вы назначаете глобальную переменную! Изменить на
this.__r = …
[…]
return this.__r;
FLEX.Login(); }
Вы ничего не возвращаете из метода INIT
по которому может быть вызван .done()
. (Кроме того, вам не хватает. .Core
доступ к .Login
) Измените его на
return this.Login();
}
Улучшение шаблона проектирования. Каждая функция, выполняющая любые асинхронные задачи, должна создать Отложенную и return
обещание для нее.
с окончательной функцией, которую я надеялся вернуть отложенный объект
Нет, это не то, как обещают работу. Начальная функция обрабатывает отложенную и возвращает обещание, функция "final" (асинхронный обратный вызов) разрешает только отложенную - которая может инициировать другие процессы ("final" является локальной для одной асинхронной задачи, а не "конечным" обработчиком в цепочке задач).
var FLEX = FLEX || {};
FLEX.Core = {
__networkIdToken: '',
__r: null,
Init: function() {
// some pseudo-action that might resemble your process
// implemented with promises
this.__r = FLEX.getAuthToken().catch(function(noAuthTokenError) {
showLoginForm();
return getNextFormSubmission().then(function(credentials) {
return serverRequest(credentials).then(function (token) {
hideLoginForm();
return token;
}, function(authError) {
// try again? Get next form submission...
});
});
}).then(function(token) {
yam.platform.setAuthToken(token);
});
return this.__r;
},
Login: function () {
var d = $.Deferred();
//Asynchronous Login Code Goes here, callback {
d.resolve();
// or
d.reject();
// }
return d.promise();
}
// similarly for the other async tasks
}
Если есть идентификатор сети, я бы хотел, чтобы обещание было возвращено здесь... удалили необходимость любой асинхронной логики для входа в систему
Вы всегда хотите вернуть обещание, даже если результат синхронно доступен. Логика для обработки, возможно, асинхронного входа должна быть асинхронной в любом случае. В вашем случае это может выглядеть так:
FLEX.getAuthToken /* as used above */ = function() {
var __networkIdToken = localStorage.getItem(FLEX_YAMMER_AUTHTOKEN);
if (__networkIdToken != null)
return $.when(__networkIdToken);
else
return $.Deferred().reject(); // the rejection will be handled by the .catch
// or maybe try another storage?
}
Complete
. Возможно, вам не следовало удалять весь асинхронный код.
return FLEX.Login()
? (Возможно также рассмотрите возможность возврата__r.promise()
изLogin()
.)