Как работать с Async Local Storage с Angular 2? - PullRequest
0 голосов
/ 05 июня 2018

Я устанавливаю срок действия токена в локальном хранилище, используя модуль локального углового асинхронного хранения.

import { AsyncLocalStorage } from 'angular-async-local-storage';

const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());

this.localStorage.setItem('expires_at', expiresAt).subscribe(() => {});

У меня есть функция, которая вызывается при входе пользователя в систему, которая проверяет, чтобы увидетьесли токен все еще действителен:

get isAuthenticated(): boolean {
    let res;
    this.localStorage.getItem('expires_at')
        .subscribe((val) => {
            let expiresAt = JSON.parse(val);
            res = (expiresAt && this.loggedIn) ? (new Date().getTime() < expiresAt) : false;
        });

    return res;
}

Проблема здесь в том, что localStorage.getItem () возвращает Observable.поэтому, когда мы вызываем .subscribe для наблюдаемой, она вызывается асинхронно, что означает, что мы не блокируем, пока результат не будет готов, поэтому код просто проходит напрямую и выполняет инструкцию return res, которая в этой точке res не определена, так каккод в функции стрелки подписки еще не выполнен, потому что результат не готов.

Итак, мне нужен совет, как лучше всего решить эту проблему?Один из подходов, о котором я подумал, состоял в том, чтобы попытаться заблокировать, пока результат не будет готов, но это выглядит как анти-паттерн, учитывая, что мы используем локальный модуль хранения ASYNC.Но, может быть, мне нужен простой синхронный модуль локального хранилища?Или это считается плохой практикой?Любая помощь будет большой благодарностью!

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Я предполагаю, что ваш пользователь уже ожидает загрузки асинхронного входа в систему, поэтому вы можете связать свой вызов localStorage с помощью flatMap:

isAuthenticated(): Observable<number> {
    return this.localStorage.getItem('expires_at')
    .map((val) => {
            let expiresAt = JSON.parse(val);
            return (expiresAt && this.loggedIn) ? (new Date().getTime() < expiresAt) : 0;
        });
}

yourLoginFunction()
.flatMap(loginRes => {
    return this.isAuthenticated()
})
.subscribe(res => {
    // handle accordingly
}

Обратите внимание, что isAuthenticated() не может иметь тип boolean или Observable<boolean> и верните метку времени.Поэтому я изменил false на 0.

0 голосов
/ 05 июня 2018

Короче говоря: в вашем случае я бы выбрал решение для синхронного локального хранения.

Длинная история:

В подобных ситуациях (синхронно или асинхронно) в Angular я всегда получал одноиз этих двух решений:

1) Пусть isAuthenticated вернет Observable и отобразит ваш localalstorage observable для возврата true / false

get isAuthenticated(): Observable<boolean> {
    return this.localStorage.getItem('expires_at').pipe(
        map((val) => {
            let expiresAt = JSON.parse(val);
            let res = (expiresAt && this.loggedIn) ? (new Date().getTime() < expiresAt) : false;
            return res;
        })
    );
}

2) Используйте синхронное решение, как вы предложили

Что является лучшей практикой, зависит от ситуации.По моему опыту, если вы сделаете это видимым образом, вы получите больше кода для обработки всех возможных и невозможных ситуаций.Также все зависимости в этом коде также должны вызываться асинхронно (например, если вы вошли в систему, отправьте HTTP-запрос, а затем обработайте его ответ).Если вы хотите обрабатывать подобные вещи СУХОЙ и в сервисах, вам придется копать глубже в RxJS и его операторы, такие как MergeAll и т. Д.

С другой стороны, если вы используете синхронное решение, ваш код будетгораздо проще, но в некоторых случаях ваше приложение может стать неудобно медленным (представьте, что HTTP-запросы синхронны в медленной мобильной сети).

Так что, если вы получаете один маленький элемент всего один раз из localStorage, вы не увидите разницы.С другой стороны, эта библиотека предоставляет вам тот же интерфейс для IndexedDb, где максимальный предел может составлять 2 ГБ данных , поэтому вы можете сохранять там целые коллекции, и тогда ускорение работы вашего приложения может быть огромным, если вы используете асинхронный способ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...