首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >角9同步执行在后面的代码订阅

角9同步执行在后面的代码订阅
EN

Stack Overflow用户
提问于 2020-02-22 12:27:33
回答 2查看 605关注 0票数 0

我需要运行一个有两个参数的方法,每个参数都是通过某种形式的订阅函数得到的。第一个是通过url从角的页面路由获得的集合。第二个是道具,这是消防队的消防队的文件。

代码语言:javascript
复制
export class FirebaseDocument implements OnInit {
   collection: string;
   dokument: any;

   //== CONSTRUCTORS
  constructor(
    private route: ActivatedRoute,
    private _db: AngularFirestore
  ) {}

  //== Initialize
  ngOnInit() {
    console.log("__loading page component");
    this.route.params.subscribe(params => {
      this.collection = params["collection"];
    });
    console.log(this.collection);//collection populated correctly

    //load the document from AngularFirestore
    console.log("loading the document from firebase");
    let itemsCollection = this._db.collection(url).valueChanges();
    
    //subscribe to get the dok of the first document in the collection
    itemsCollection.subscribe(docArr => {
        this.dokument = docArr[0];
        console.log(this.dokument);//dokument is populated
    });
    
    console.log(this.dokument);//dokument is undefined
    this.doMultiParameterMethod(this.collection, this.dokument);
  }
}

this.collection填充得非常好;this.dokument只在订阅方法中填充。

我需要在下一行运行时填充它。console.log(this.dokument);

我对此感到震惊,因为2订阅方法使用的代码本质上是相同的,但它们的行为方式不同。

EN

回答 2

Stack Overflow用户

发布于 2020-02-22 12:35:53

有时,订阅可以是同步的。当ObservableReplaySubjectBehaviorSubject或有shareReplay()管道的Observable时,就会发生这种情况。(可能还有其他选择。

这将使可观察到的立即启动订阅。但是,您不应该指望这种行为,并且始终在您的订阅范围内继续。或者使用像mergeMap这样的管道,并创建其他可观察的对象,您可以使用async管道在模板中访问它们。

在你的案子里。this.route.params显然是一个“回放”,您可以从它获得订阅后的最新值。否则,您将不得不等待参数再次更改,直到得到一个值。

数据库调用不能立即返回响应,因为它本质上是一个网络请求。

在示例代码中,可以将其更新为此,并在模板中使用async管道。

代码语言:javascript
复制
export class FirebaseDocument implements OnInit {
   readonly collection$: Observable<string> = this.route.params.pipe(
     map((params) => params.collection)
   );

   readonly doc$: Observable<any[]> = this.db.collection(this.url).valueChanges().pipe(
     shareReplay({ refCount: true, bufferSize: 1 })
   );

   constructor(private route: ActivatedRoute, private db: AngularFirestore) {}

  ngOnInit() {
    // don't forget to unsubscribe
    combineLatest([
      this.collection$,
      this.doc$
    ]).subscribe((collection, document) => {
      this.doMultiParameterMethod(collection, document);
    }); 
  }
}
票数 0
EN

Stack Overflow用户

发布于 2020-02-22 13:34:45

也许你应该做出一个可以观察到的承诺,在你的情况下,如下所示:

代码语言:javascript
复制
export class FirebaseDocument implements OnInit {
 collection: string;
 dokument: any;

 //== CONSTRUCTORS
 constructor(
  private route: ActivatedRoute,
  private _db: AngularFirestore
 ) {}

 //== Initialize
 ngOnInit() {
  console.log("__loading page component");
  this.route.params.subscribe(params => {
   this.collection = params["collection"];
  });

  console.log(this.collection); //collection populated correctly

  this.getDokument().then(docArr => {
   this.dokument = docArr[0];
   this.doMultiParameterMethod(this.collection, this.dokument);
  });

 }

 getDokument(): Promise<any> {
  let itemsCollection = this._db.collection(url).valueChanges();
  return new Promise((resolve, reject) => {
   itemsCollection.subscribe((response: any) => {
    resolve(response);
   }, reject);
  });
 }

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60352142

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档