2015-10-19 3 views
0

Функция getIdentityTokenDecrypted дает мне трудное время. Я хотел бы вернуть обещание от decryptToken СЕРВИС B до getToken СЕРВИС A, чтобы получить токен.Как вернуть обещание от функции?

Вот шаги, которые мне нужно:

  1. Получить outlookService.mailbox.getUserIdentityTokenAsync результат. (Дает зашифрованный токен)
  2. Дешифровать токен через $http route /api/exchange/createAndValidateIdentityToken. Этот запрос возвращает токен, который мне нужен в SERVICE A.

Как я могу заставить это работать?

/*** SERVICE A ***/ 

var service = { 
    /*...*/ 
    token: getToken() 
}; 

return service; 

function getToken() { 
    var token; 

    serviceB.getIdentityTokenDecrypted() 
     .then(function successCallback(response) { 
      token = response.data.UniqueUserIdentification; 
      return token; 
     }, function errorCallback(response) { 
      return null; 
     }); 
} 

/*** SERVICE B ***/ 

function getIdentityTokenDecrypted() { 
    var token = null; 
    var promise; 

    // This async call does not return a promise, 
    // I don't think I can chain after it. 
    outlookService.mailbox.getUserIdentityTokenAsync(function (res) { 
     token = res; 
    }); 

    // That's why I use an interval 
    promise = $interval(function() { 
     if (token != null) { 
      $interval.cancel(promise); 
      return decryptToken(); 
     } 
    }, 100); 

    function decryptToken() { 
     var location = window.location.href; 

     // I need to get the 'data' from the success 
     // of this request to retrieve the token 
     return $http({ 
      method: "POST", 
      url: "/api/exchange/createAndValidateIdentityToken", 
      data: JSON.stringify({ 
       userIdentityToken: token, 
       location: location 
      }) 
     }); 
    }; 
    return promise; 
}; 
+0

Существует первый параметр, который является методом обратного вызова: https://msdn.microsoft.com/en-us/library/office/fp142236.aspx Хотя это приводит к той же проблеме, я не знаю, как возвратите обещание вызова $ hhtp от этой функции обратного вызова. – Elfayer

ответ

4

Поскольку outlookService.mailbox.getUserIdentityTokenAsync обеспечивает обратный вызов, вам не нужно $interval. Вы можете обещать любую асинхронную функцию, которая дает вам обратный вызов, создавая свое собственное обещание (это нормально, когда это неизбежно), а затем урегулировать его с обещанием, которое вы получаете от $http, когда у вас есть это (чего вы не будете, пока обратный вызов для getUserIdentityTokenAsync).

Я не «делать» угловой, но, видимо, $q has a "streamlined" syntax скорее как ES2015-х:

promise = $q(function(resolve, reject) { 
    outlookService.mailbox.getUserIdentityTokenAsync(function (res) { 
     if (/*...presumably there's some failure condition...*/) { 
      reject(/*...*/); 
     } else { 
      token = res; 
      resolve(decryptToken()); 
     } 
    }); 
}); 

(я бы, вероятно, также изменить decryptToken принять маркер в качестве аргумента, а не имеющие переменную token.)

Ключевым недостатком является то, что если вы разрешите обещание с другим обещанием, которое будет распространяться по цепочке.

+1

«Использовать обратный вызов, а не $ interval», вы правы, что не имеет смысла. ^^ – Elfayer

+0

@Elfayer: Мне стыдно сказать, что я не заметил, что вы использовали обратный вызов, пока я уже не написал большую часть ответ, который открывается с тем же абзацем, за которым следует «Но это не меняет того факта, что вам нужно как-то получить обещание из ситуации обратного вызова», а затем показал выше, но с интервалом. К счастью, я поймал это вовремя. :-) Но теперь я просто полностью удалил первый абзац, это не помогло. –

+0

Поскольку речь идет о AngularJS OP, было бы лучше пойти с сервисом [$ q] (https://docs.angularjs.org/api/ng/service/$q). Это почти такой же синтаксис, но завернутый в '$ watch' – Guilherme

Смежные вопросы