嵌套可观察项完成时,Angular 10调用finalize

问题描述

在处理完最后一项之后,对嵌套的可观察对象进行最终化。 Stackblitz

finableize()在可观察对象完成时应调用-输出所有数字(11、12、13)。

可观察物应如何嵌套?

import { from } from "rxjs";
import { map,finalize } from "rxjs/operators";

//emit (1,2,3)
const data = [
  {
    userId: 1,id: 1
  },{
    userId: 1,id: 2
  },id: 3
  }
];
const source = from(data);
//add 10 to each value
const example = source.pipe(map(val => add(val.id)));
//output: 11,12,13
const subscribe = example.subscribe(val => console.log(val));
function add(n) {
  return n + 10;
}

Stackblitz是一个起点。

在下面的代码中,我想向所有用户发送一条消息。

所有消息发送完毕后,我想退订并关闭模式。

  submit() {
    const users = from(this.form.value.users).pipe(
      finalize(() => {
        console.log('finalize'),this.dismissModal()
      }),map(user => this.buildMessage(user))
    ).subscribe(message => {
      this.subscription = this.firestoreService.addMessage(message)
        .subscribe();
    });
  }

  ngOnDestroy(): void {
    this.subscription?.unsubscribe();
  }

  dismissModal() {
    this.dialogRef.close('modal dismissed');
  }

现在firestoreService.addMessage(message)记录console.log('addMessage')并返回但不将消息添加数据库中。

  addMessage(data:Message):Observable<T> {
    console.log('addMessage');
    data.timestamp = firebase.firestore.FieldValue.serverTimestamp();
    return this.authService.currentUser$.pipe(
      switchMap(user => {
        console.log('addMessage user: ',user);
        if (user) {
          return this.firestore
            .collection<any>(user.company)
            .doc(user.licence)
            .collection<any>(message)
            .add(data)
              .then(res => {
                console.log("Message successfully added! ",res);
              })
              .catch(e => {
                console.error("Error adding message: ",e);
              });
          } else {
            return [];
          }
        }
      )
    );
  }

解决方法

在这种情况下,您应该使用高阶运算符 switchMap

使用switchMap,您可以订阅buildMessage(user)并将其可观察到的结果仅通过一个管道操作传递给firestoreService.addMessage(message)

submit() {
  this.subscription = from(this.form.value.users).pipe(
    finalize(() => {
      console.log('finalize'),this.dismissModal()
    }),map(user => this.buildMessage(user)),switchMap((message) => this.firestoreService.addMessage(message))
  ).subscribe();
}

ngOnDestroy(): void {
  this.subscription?.unsubscribe();
}

dismissModal() {
  this.dialogRef.close('modal dismissed');
}

已编辑

您需要以这种方式返回Observables。 from从诺言中创建可观察的事物 of根据序列中的值创建可观察值

 addMessage(data:Message):Observable<T> {
    console.log('addMessage');
    data.timestamp = firebase.firestore.FieldValue.serverTimestamp();
    return this.authService.currentUser$.pipe(
      switchMap(user => {
        console.log('addMessage user: ',user);
        if (user) {
          return from(this.firestore
            .collection<any>(user.company)
            .doc(user.licence)
            .collection<any>(message)
            .add(data))
          } else {
            return of([]);
          }
        }
      )
    );
  }