Разрешение асинхронного значения из класса JS - PullRequest
0 голосов
/ 05 января 2019

Вкратце: мне нужно запросить токен у Auth0, чтобы затем получить информацию о пользователе (все внутри плагина Vue, который вызывается Vuex).

В настоящее время у меня есть два класса - один для работы с токеном, а другой - для получения профиля.

export class Token {
  constructor () {
    this.options = { method: 'POST',
      url: 'https://.auth0.com/oauth/token',
      headers: { 'content-type': 'application/json' },
      body: '{"client_id":"","client_secret":"","audience":"","grant_type":"client_credentials"}' }
  }

  async getToken () {
     try {
       this.request = request(this.options, function (error, response, body) {
         if (error) {
           console.error(error)
         } else {
           let parsed = JSON.parse(body)
           let token = parsed.access_token
           return token
         }
       })
       let blah = await this.request
       console.log(blah)
     } catch (err) {
       console.error(err)
     }
  }
}

export default class Profile {
  constructor () {
    const token = new Token()
    let result = token.getToken()
    //console.log(result)
    this.auth0Manage = new auth0.Management({
      domain: '.auth0.com',
      token: `${result}`
    })
  }

  getProfile () {
    return new Promise((resolve, reject) => {
      let idToken = localStorage.getItem('id_token')
      let decoded = jwt_decode(idToken)
      let userId = decoded.sub
      this.auth0Manage.getUser(userId, function (err, data) {
        if (err) {
          console.error(err)
        }
        resolve(data)
      })
    })
  }
}

Я ожидаю следующий поток:

Получить токен> Получить профиль. Это не обязательно должно быть в двух классах (изначально это не было, но я не смог создать экземпляр конструктора для Profile, не получив сначала токен, который должен был быть его собственным классом (afaik). Спасибо!

1 Ответ

0 голосов
/ 05 января 2019

Похоже, вы не ожидаете результата getToken в конструкторе профиля. Проблема в том, что конструкторы всегда синхронны. Поэтому, чтобы дождаться токена, вам нужно сделать что-то вроде сделать Profile#auth0manage асинхронным значением и дождаться его. Может быть, как:

export default class Profile {
  constructor () {
    let token = new Token()
    this.auth0Manage = new Promise((resolve, reject) => {
      token.getToken().then((result) => {
        return new auth0.Management({
          domain: '.auth0.com',
          token: `${result}`
        })
      }).then(resolve, reject)
    })
  }

  async getProfile () {
    let auth0Manage = await this.auth0Manage
    return new Promise((resolve, reject) => {
      let idToken = localStorage.getItem('id_token')
      let decoded = jwt_decode(idToken)
      let userId = decoded.sub
      auth0Manage.getUser(userId, function (err, data) {
        if (err) {
          console.error(err)
        }
        resolve(data)
      })
    })
  }
}

Предостережения в том, что если вы получите ошибку в getToken, то каждый вызов getProfile будет возвращать одну и ту же ошибку. Так что вы можете как-то с этим справиться. Кроме того, вы должны помнить, чтобы ждать каждого использования this.auth0Manage. В идеале вы могли бы сделать что-то вроде передачи auth0Manager в конструктор Profile, чтобы событие не пыталось создать профиль, пока токен не будет выбран. Имеет тенденцию работать лучше, чтобы делать вещи таким образом.

...