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

时间:2017-11-08 07:00:53

标签: angular typescript rxjs observable

我有两个组成部分。子组件有一个事件(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
    }
}

我尝试使用async-await方法:

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

序列已更改,但仍然不正确:1 - &gt; 2 - &gt; 5 - &gt; 3 - &gt; 4。 如何做到正确的行为?

2 个答案:

答案 0 :(得分:2)

延迟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
  }
}

准备好时在父级中执行execStep5

handleChildEvent(execStep5) {
  ...
// Step 4: Another code
execStep5();

对于step3&amp;第4步,将subscribe更改为map 然后 订阅并执行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();
      });
  }
}

执行此操作的代码可能更短,但这应该可行。

答案 1 :(得分:1)

我在类似的情况下尝试过这种解决方案但不完全一样。由于您现在的问题仅在于步骤5没有按顺序排列,因此您可以将步骤5包含在setTimeout函数中,并等待0。这将导致步骤5成为计划任务。

    setTimeout(_ => {/*step 5 code*/});