Обертывание функции parseHash Auth0 в обещание

auth0.js имеет функцию, которая используется для анализа фрагмента хэша URL и извлечения из него результата аутентификации. Я оборачиваю эту функцию в одну с именем loadSession следующим образом:

public loadSession(): void {
  this.auth0.parseHash((err, authResult) => {
    if (authResult) {
      window.location.hash = '';
      localStorage.setItem('token', authResult.accessToken);
      // TODO (1)
    } else if (err) {
      // TODO (2)
    }
  });
}

Как видно выше, parseHash принимает функцию обратного вызова в качестве аргумента, и я не могу это контролировать. Я хотел бы, чтобы loadSession возвращал Promise, который был бы разрешен в // TODO (1) и отклонен в // TODO (2) выше. Таким образом, я могу сделать obj.loadSession().then(() => { // do something if successful }).catch((err) => { // raise error if not })


person Sammy    schedule 03.12.2017    source источник


Ответы (4)


Просто оберните его внутри обещания:

public loadSession() {
    return new Promise((resolve, reject) => {
        this.auth0.parseHash((err, authResult) => {
            if(authResult) {
                window.location.hash = '';
                localStorage.setItem('token', authResult.accessToken);
                resolve(authResult);
            } else if (err) {
                reject(err);
            }
        });
    });
}
person Kartik Sharma    schedule 03.12.2017

Вы можете практически передать любую функцию обратного вызова функции, которая возвращает данное обещание:

  1. Обратный вызов является последним аргументом
  2. Функция обратного вызова принимает ошибку в качестве первого аргумента

Вот пример:

const asPromise = 
  (context)   =>
  (fn)   =>
  (args)      =>
    new Promise(
      (resolve,reject) =>
        fn.apply(
          context,
          (args||[]).concat(
            function(){
              if(arguments[0]){
                reject(arguments[0]);return;
              }
              resolve(Array.from(arguments).slice(1));
            }
          )
        )
    );

// to apply parseHash on auth0
public loadSession(): Promise {
  return asPromise(this.auth0)(this.auth0.parseHash)()
  .then(
    ([authResult])=>{
      if (authResult) {
        window.location.hash = '';
        localStorage.setItem('token', authResult.accessToken);
        //whatever you return here is the resolve
        return authResult;
      } 
      //just throw in a promise handler will return a rejected promise
      // this is only for native promises, some libraries don't behave
      // according to spec so you should test your promise polyfil if supporting IE
      throw "Promise resolved but got no authResult";
    }
  )
}
person HMR    schedule 03.12.2017

public loadSession(): Promise {
  return new Promise((resolve, reject) => {
    this.auth0.parseHash((err, authResult) => {
    if (authResult) {
      window.location.hash = '';
      localStorage.setItem('token', authResult.accessToken);
      // TODO (1)
      // resolve(something)
    } else if (err) {
      // TODO (2)
      // reject(something)
    }
  });
}

Для получения дополнительной информации об использовании Promise API вы можете посетить MDN. Документы

person SALEH    schedule 03.12.2017

Или вы можете использовать крошечную библиотеку, которая сделает это за вас: promisify-auth0 на GitHub, promisify-auth0 на npmjs.org.

Сейчас обновлен до версии 9.5.1.

person Igor Soloydenko    schedule 03.12.2017