代码之家  ›  专栏  ›  技术社区  ›  Kyle V.

检查一组可观察对象是否以同步方式完成?

  •  0
  • Kyle V.  · 技术社区  · 6 年前

    Observables : source1$ source2$

    因为用户可以在任何时候单击按钮,所以我希望能够检查是否有任何Web API请求处于挂起状态,以及它们是否处于挂起状态,然后不执行任何操作—否则保存。

    我在想象这样的事情:

    saveButton_onClicked() {
        if (// source1$ and source2$ are completed) {
            this.saveForm();
        }
    }
    

    在任何时候,这些可观察对象中的任何一个都可以被分配给一个新的可观察对象(例如,当数据被刷新时),我认为 forkJoin 会在这里工作,因为我需要知道 实时 如果表单是否应该保存,我不希望click事件等待 叉形连接 可观察到要解决。

    有什么想法吗?

    2 回复  |  直到 6 年前
        1
  •  3
  •   martin    6 年前

    实际上,我认为最简单的方法是 forkJoin finalize 运算符,而不是检查源对象本身,而是创建一个属性。 loading 您可以随时检查并查看是否存在挂起的可观察项:

    whatever() {
      this.loading = true;
    
      forkJoin(source1$, source2$)
        .pipe(
          finalize(() => this.loading = false)
        )
        .subscribe();
    }
    
    saveButton_onClicked() {
      if (!this.loading) {
        ...
      }
    }
    
        2
  •  1
  •   Alberto Chiesa    6 年前

    嗯,给猫剥皮有很多方法。 有些人比其他人更优雅。我更喜欢将额外可观察属性的数量保持在最小,在这种情况下似乎是2。我会添加一个属性 isRunningRequest$ ,其发出的值为标志,如果当前有正在运行的操作,则为true。这个标志将由另一个可观察到的, asyncAction$ ,用于跟踪当前正在运行的操作:

    export class AsyncActionData {
      actionType: 'start' | 'end';
      actionToken: string;
    }
    
        public asyncAction$ = new Subject<AsyncActionData>();
    
        public isRunningRequest$ = new BehaviorSubject<boolean>(false);
    
        constructor(...) {
            this.asyncAction$
                .pipe(
                    // we keep an array of currently running actions, and add
                    // or remove from the array according to the action type
                    scan((arr: string[], action: AsyncActionData) => {
                        return action.actionType === 'start'
                            ? arr.concat(action.actionToken)
                            : arr.filter(action => action !== action.actionToken);
                    }, []),
                    map(arr => arr.length === 0 ? false : true)
                )
                .subscribe(requestsAreRunning => this.isRunningRequest$.next(requestsAreRunning));
        }
    

    异步操作$ :

    this.asyncAction$.next({actionType: 'start', actionToken: 'action1'});
    this.http.post(...)
       .subscribe(result => ...,
                  null,
                  () => this.asyncAction$.next({actionType: 'end', actionToken: 'action1'})
       );
    

    (所有代码都未经测试,但想法应该是合理的)

    here here scan 接线员。