【问题标题】:How can I obtain result of function inside setInterval?如何获得 setInterval 内的函数结果?
【发布时间】:2021-05-07 21:40:30
【问题描述】:

我正在尝试让我的用户通过以下步骤更新他们的 SSO 令牌:

-如果检测到过期,则使用模式提示用户要求用户登录: - 如果用户确认(点击“启动”),使用 sso url 启动窗口 -一旦启动,从新窗口检测令牌,将其设置为新的访问令牌,然后关闭窗口

窗口是在一个setInterval函数内部启动的,我不知道如何将这个是否成功的布尔结果返回给调用函数。下面是相关代码,如何从 setInterval 中返回布尔结果?

refreshSSO 打开 matDialog。如果用户选择“启动”,则打开到 doAuth 以启动 SSO 窗口并检测新令牌

  refreshSSO(): Observable<boolean> {
    const refresh_uri = <sso endpoint>;
    const config = matDialogHelpers.getDefaultConfig({});
    const matDialogRef: MatDialogRef<LaunchRefreshComponent> = this.matDialog.open(LaunchRefreshComponent, config);

    return matDialogRef.afterClosed().pipe(
      map(
      next => {
        if (next === 'launch') {
          return this.popupAuth(refresh_uri);
        } else {
          return false;
        }
      })
    );
  }
  popupAuth(authUrl: string): boolean {
    this.intervalId = window.setInterval(() => { this.insideInterval(authUrl); }, this.intervalLength);
    return this.intervalId;
  }

insideInterval 打开带有 sso 的窗口,倒计时,并检查新的 accessToken。如果找到,则设置令牌,返回 true,然后关闭。如果时间用完,返回 false 并关闭。

  insideInterval(authUrl: string): boolean {
    let windowHandle: Window;  
    let loopCount = this.loopCount;
    /* Create the window object by passing url and optional window title */
    windowHandle = this.createOauthWindow(authUrl, 'OAuth login');
    if (loopCount-- < 0) {
      window.clearInterval(this.intervalId);
      windowHandle.close();
      return false;
    } else {
      let href: string;  // For referencing window url
      try {
        href = windowHandle.location.href; // set window location to href string
      } catch (e) {
        console.log('Error:', e); // Handle any errors here
      }
      if (href != null) {
        /* As i was getting code and oauth-token i added for same, you can replace with your expected variables */
        if (href.match('access_token')) {
          // for twitter
          window.clearInterval(this.intervalId);
          const newToken = this.getQueryString('access_token', href);
          localStorage.setItem('accessToken', newToken);
          windowHandle.close();
          return true;
        }
      }
    }
  }

createOauthWindow 只是打开一个带有给定 URL 的弹出窗口

  createOauthWindow(url: string, name = 'Authorization', width = 500, height = 600, left = 0, top = 0) {
    if (url == null) {
      return null;
    }
    const options = `width=${width},height=${height},left=${left},top=${top}`;
    return window.open(url, name, options);
  }

【问题讨论】:

    标签: javascript node.js angular setinterval async.js


    【解决方案1】:

    考虑保留它 RxJs: https://www.learnrxjs.io/learn-rxjs/operators/creation/timer

     popupAuth(authUrl: string): Observable<boolean> {
       return timer(this.intervalLength, this.intervalLength).pipe(
         map(() => this.insideInterval(authUrl))
       )
     }
    

    然后,您可以在refreshSSO 中使用相应的地图。

    查看这篇文章:https://blog.angular-university.io/rxjs-higher-order-mapping/

    例如:

    refreshSSO(): Observable<boolean> {
        const refresh_uri = <sso endpoint>;
        const config = matDialogHelpers.getDefaultConfig({});
        const matDialogRef: MatDialogRef<LaunchRefreshComponent> = this.matDialog.open(LaunchRefreshComponent, config);
    
        return matDialogRef.afterClosed().pipe(
          mergeMap(
            next => {
              if (next === 'launch') {
                return this.popupAuth(refresh_uri); // This might not complete, unless you take care of it. Look into take/takeUntil/takeWhile operators. 
              } else {
                return of(false); // This one will complete immediately.
              }
          })
        );
      }
    

    记得完成或取消订阅 Observable 以防止泄漏。

    例如:

    const subscription = this.refreshSSO().subscribe((value) => {
      if(value == isWhatNeeded) {
        subscription.unsubscribe();
      } 
    });
    

    【讨论】:

    • 谢谢你,@tropicana。这是一个基本的 Angular 问题,但我仍然要问,refreshSSO 中合适的映射是什么?因为我有以下内容,这会导致 Observable>: ``` return matDialogRef.afterClosed().pipe( map( next => { if (next === 'launch') { return this.doAuthorization (refresh_uri).map(x => x); } }) ); ```
    猜你喜欢
    • 1970-01-01
    • 2022-11-20
    • 1970-01-01
    • 2021-02-27
    • 1970-01-01
    • 2015-04-28
    • 1970-01-01
    • 2012-04-02
    • 2014-04-25
    相关资源
    最近更新 更多