【问题标题】:Firebase .equalto function resolve before executing rest of the codeFirebase .equalto 函数在执行其余代码之前解析
【发布时间】:2022-11-28 06:33:46
【问题描述】:

我正在尝试使用此服务 getTodaysRoute() ,在这里我使用 .equalTo 找出今天的路由节点密钥,然后根据我的理解,我必须使用此 .on 函数快照,然后我终于可以从中获得密钥我使用此键将数据作为可观察对象获取。问题发生在 .on 函数中的代码最后执行并且第一次页面加载时我的 todaysroutekey 是未定义的。我怎样才能避免这样的情况?

getTodaysRoute(): Observable<Location[]> {
    const date = new Date().toISOString().replace(/\T.*/, '');
    const userdate = `${this.useremail}${date}`;
    let todaysroutekey;
     this.db.database 
      .ref()
      .child('routes')
      .orderByChild('user_date')
      .equalTo(userdate)
      .on('child_added', function ( snapshot) {
       
        todaysroutekey =  snapshot.key;

      });
     
    console.log(todaysroutekey);
    return this.db
      .list(`${this.routesUrl}/${todaysroutekey}/locations`)
      .snapshotChanges()
      .pipe(
        map((locations) =>
          locations.map(
            (location) =>
              ({
                key: location.payload.key,
                ...(location.payload.val() as {}),
              } as unknown as Location)
          )
        )
      );
  }

这是我的组件代码

  routeLocations: any[];

  constructor(private firebase: FirebaseService) { }

  ngOnInit(): void {
    this.firebase.getTodaysRoute().subscribe((value) => {
      this.routeLocations = value;
    });
  }

【问题讨论】:

    标签: angular firebase firebase-realtime-database observable angularfire


    【解决方案1】:

    这是预期的行为,因为 on(与大多数现代云 API 一样)是异步操作。

    处理这个问题的一种方法是将第二个查询嵌套在第一个查询的 on 回调中:

    const date = new Date().toISOString().replace(/T.*/, '');
    const userdate = `${this.useremail}${date}`;
    let todaysroutekey;
     this.db.database 
      .ref()
      .child('routes')
      .orderByChild('user_date')
      .equalTo(userdate)
      .on('child_added', function ( snapshot) {       
        todaysroutekey =  snapshot.key;
    
        console.log(todaysroutekey);
    
        return this.db
          .list(`${this.routesUrl}/${todaysroutekey}/locations`)
          .snapshotChanges()
          .pipe(
            map((locations) =>
              locations.map(
                (location) =>
                  ({
                    key: location.payload.key,
                    ...(location.payload.val() as {}),
                  } as unknown as Location)
              )
            )
          );
      });
    

    不过,在这种情况下,您将无法返回 Observable。我建议研究使用once(而不是on)并查看async/await

    【讨论】:

    • 您能否展示一下如何使用 async await 完成此操作?如果我能看到它在我的项目中运行,那将对学习过程有很大帮​​助
    【解决方案2】:

    经过 2 周的几乎所有尝试后,这就是解决方案:

    async getTodaysRoute(): Promise<Observable<Location[]>> {
    const date = new Date().toISOString().replace(/T.*/, '');
    const userdate = `${this.useremail}${date}`;
    let todaysroutekey;
    await this.db.database
      .ref()
      .child('routes')
      .orderByChild('user_date')
      .equalTo(userdate)
      .once('child_added', function (snapshot) {
        todaysroutekey = snapshot.key;
      });
    
    return this.db
      .list(`${this.routesUrl}/${todaysroutekey}/locations`)
      .snapshotChanges()
      .pipe(
        map((locations) =>
          locations.map(
            (location) =>
              ({
                key: location.payload.key,
                ...(location.payload.val() as {}),
              } as unknown as Location)
          )
        )
      );
    

    }

    this.firebase.getTodaysRoute().then(
      (event) =>
        event.subscribe(
          (value: any) =>
            (this.routeLocations = value.sort((a, b) => a.id - b.id))
        )
    );
    

    【讨论】:

      猜你喜欢
      • 2018-02-15
      • 1970-01-01
      • 2018-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-20
      相关资源
      最近更新 更多