如何使用 Observable 调用等待事件订阅者完成

x66*_*6ep 7 observable rxjs typescript angular

我有两个组件。子组件有一个事件(EventEmitter)。父组件具有长时间方法的处理程序。

在进一步操作之前,我需要等待我的方法(longTimeMethod)的执行完成。方法继续接近 5 秒。

我想一致地执行所有步骤(1 -> 2 -> 3 -> 4 -> 5)。

但现在序列是 1 -> 2 -> 4 -> 5 -> 3

@Component({
    selector: 'child-selector',
    template: '<>********</>'
})
export class ChildComponent{
    @Output() childEvent = new EventEmitter();

    someFunction() {
       // Step 1: event emit

        this.childEvent.emit();
        // Step 5: Subscribers execution finished
        // Some code which should to reached after all event subscribers
    }
}

@Component({
    selector: 'parent-selector',
    template: '<child-selector (childEvent)="handleChildEvent()"></child-selector>'
})

export class ParentComponent{
       // Step 2: handler start 
    handleChildEvent() {
        // this.longTimeMethod return Observable<void>
        this.myService.longTimeMethod()
            .subscribe(() => {
                // Step 3: Method executing finished
            });
    // Step 4: Another code
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用 async-await 方法:

async handleChildEvent() {
    // this.longTimeMethod return Observable<void>
    await this.myService.longTimeMethod().toPromise()
        .then(() => {
            // Step 3: Method executing finished
        });
       // Step 4: Another code
}
Run Code Online (Sandbox Code Playgroud)

顺序改变了,但仍然不正确:1 -> 2 -> 5 -> 3 -> 4. 如何完成正确的行为?

Ric*_*sen 6

延迟 step5 发出来自孩子的回调。

export class ChildComponent{
  @Output() childEvent = new EventEmitter();

  someFunction() {
    // Step 1: event emit
    this.childEvent.emit(execStep5);
  }

  execStep5() {
    // Step 5: Subscribers execution finished
    // Some code which should to reached after all event subscribers
  }
}
Run Code Online (Sandbox Code Playgroud)

execStep5准备好后在父级中执行

handleChildEvent(execStep5) {
  ...
// Step 4: Another code
execStep5();
Run Code Online (Sandbox Code Playgroud)

对于 step3 & step4,更改subscribemap然后订阅并执行 step4 和回调。
不要使用 await/async,因为 rxjs 已经有了这些工具——不要混合使用两种方法。

export class ParentComponent{
  // Step 2: handler start 
  handleChildEvent(execStep5) {
    // this.longTimeMethod return Observable<void>
    this.myService.longTimeMethod()
      .map(() => {
        // Step 3: Method executing finished
        return Observable.of('done');
      })
      .subscribe(() => {
        // Step 4: Another code
        execStep5();
      });
  }
}
Run Code Online (Sandbox Code Playgroud)

可能有更短的代码来做到这一点,但这应该可行。