Переключение между двумя потоками (Observables) - PullRequest
0 голосов
/ 18 июня 2019

То, что я пытаюсь сделать, это отслеживать сеанс пользователя на основе существования куки. Я автоматически выхожу из системы, если время сеанса истекло. Чтобы это произошло, я жду, чтобы сначала появился файл cookie, т. Е. Ожидаю, когда пользователь сделает правильный вызов API. Затем я начинаю запрашивать печенье, пока его больше нет. Код ниже работает для меня в первый раз. Однако после подписки на первый поток я не могу восстановить его, когда пользователь начинает новый сеанс без перезагрузки браузера.

Код:

private _setupSession(): void {

    const waitForCookie = interval(1000)
      .pipe(
        tap(() => {
          console.log('waiting');
        }),
        switchMap(() => of(this._cookieService.get(COOKIE_STRING))),
        filter((val) => !!val),
        take(1));

    const queryCookie = interval(1000)
      .pipe(
        tap(() => {
          console.log('querying');
        }),
        switchMap(() => of(this._cookieService.get(COOKIE_STRING))),
        distinct());

    waitForCookie.pipe(concatMap(() => queryCookie))
      .subscribe(
        (val) => {
          if (!val) {
            this._router.navigate([''], {queryParams: {sessionTimedOut: true}});
          }
        },
        (err) => {
          console.log(err);
        });
  }

Наблюдение: Пока пользователь находится на странице входа в систему, я могу видеть журналы wait каждую секунду. Когда пользователь входит в систему, я начинаю видеть ' запросов ' журналов каждую секунду. По истечении времени сеанса пользователь возвращается на страницу входа. На данный момент я все еще вижу « запрашивающие » журналы в консоли. Что я хотел бы сделать, так это переключиться обратно на ' ожидание ' и переключиться на ' запрос ', как только пользователь снова войдет в систему.

Ответы [ 2 ]

1 голос
/ 18 июня 2019

Оформить заказ cookies.onChanged API .Вы можете настроить Observable с помощью fromEventPattern , а затем выполнять действия в зависимости от изменения.Реализация может выглядеть так:

const signedIn$ = fromEventPattern(
 handler => browser.cookies.onChanged.addListener(handler),
 handler => browser.cookies.onChanged.removeListener(handler)
).pipe(
  map(changeInfo => changeInfo.cookie.name === 'myCookie' && changeInfo.removed)
 )
);

signedIn$.subscribe(signedIn => {
  if (signedIn) {...}
  else {...}
})
1 голос
/ 18 июня 2019

Если я понял ваше требование, то это то, что вы хотите сделать:

Следите за cookie-файлом из метода this._cookieService.get(), а если значение null/empty/undefined, тогда направьте пользователя на страницу входа.и продолжайте наблюдать значение this._cookieService.get() каждую 1 секунду.

Если мое понимание верно, то:

Я думаю, что вы можете достичь этого, используя только один поток, подобный этому:

const queryCookie = interval(1000)
      .pipe(        
        switchMap(() => of(this._cookieService.get(COOKIE_STRING))),
        //skipwhile will ensure to avoid timeout on starting of the page/app
        skipWhile(cookie => !cookie)
      );

queryCookie
      .subscribe(
        (val) => {
          if (!val) {
            this._router.navigate([''], {queryParams: {sessionTimedOut: true}});
          }
        },
        (err) => {
          console.log(err);
        });

Кстати - я бы посоветовал не делать запросы каждую 1 секунду.Я предполагаю, что ваше приложение может установить cookie как null / empty / undefined в localStorage как-то.Если это так, то вы можете сделать свой код немного лучше, используя Subject / BehaviorSubject, и вы можете избежать запросов в 1 секунду.Это всего лишь наблюдение, так как я не знаю о дизайне вашего приложения.

...