【问题标题】:Is emitting another Observable from finalize() operator a good practice?从 finalize() 运算符发出另一个 Observable 是一种好习惯吗?
【发布时间】:2020-08-19 00:04:05
【问题描述】:

finalize() 操作符中使用自己的订阅执行另一个 observable 真的很好吗? 我知道,将其放入 subscribe() 不是一个好习惯,这会导致内存泄漏等。我目前正在使用 Firebase Storage API 并尝试将图像上传到数据库,当你无法获得正确的上传状态。因此,我试图了解,当我可以从数据库中获取图像的 URL 时,作为响应,传输的字节数等于总字节数。但 Firebase 对此作出回应,我的图像在服务器上尚不存在。

所以我必须在 finalize() 运算符中获取图像 URL。这真的是个好主意吗?

另外,可以使用debounceTime() 来实现,但我想让代码更加清晰和同步。

另外,搜索了不同的解决方案,发现了一些文章,作者做了同样的事情

      this.storage.upload(filePath, this.selectedImage).snapshotChanges()
        .pipe(
          rxFilter(res => res.bytesTransferred === res.totalBytes),
          switchMap(res => this.storage.ref(filePath).getDownloadURL())
        )
        .subscribe(url => {
          console.log(url);
        });

【问题讨论】:

  • 有一些机制可以组合 observables,例如 forkJoin。您也可以在请求完成后.pipe 进行回调。
  • @amphetamachine 我需要在上传图片后准确获取 URL。不幸的是,我无法获得正确的上传状态,我试图通过比较传输的字节量来了解上传是否完成,但在这种情况下,Firebase 仍然会响应错误
  • 请贴出有问题的代码。
  • 代码对我来说看起来不错。它会起作用,而且我没有看到其他方法。
  • @amphetamachine,是的,此代码有效。问题是这种做法是否与将带有订阅的新 Observable 放在第一个订阅中一样糟糕(内存泄漏、回调地狱等),或者不是

标签: angular typescript rxjs firebase-storage


【解决方案1】:

这绝对是一种不好的做法,不建议这样做。有很多潜在的缺点和竞争条件通常由 RxJS 处理,你需要自己处理。根据您的问题,有不同的方法可以做到这一点。我不明白整个问题,但听起来你想/应该使用switchMapconcat

【讨论】:

  • 这就是Firebase响应问题的关键所在。当我尝试上传 1.5 MB 的文件时,在上传 Firebase 对象时,FireUploadTask 有两个 Observable 方法(snapshotChanges()percentageChanges()),可以跟踪上传进度。但是,在它们以 100% 上传的情况下发出最后一个值后,我尝试立即通过 switchMap() 打开下一个流,并且 Firebase 以错误响应,即我的文件尚不存在于数据库中。所以,我需要等待,也许可以使用debounceTime(0),然后响应就会成功
  • 另外,我在我的代码中只使用last() 运算符而不是filter() 成功了,这很有效。也许,这是因为特定的 Firebase 库是如何为 Angular 完成的(使用 ngZone)。无论如何,感谢您的回答,我的主要目标是知道,如果在 finalize() 内部执行另一个 observable 是否和在 subscribe() 内部一样糟糕
猜你喜欢
  • 1970-01-01
  • 2012-01-03
  • 2020-02-06
  • 2012-04-12
  • 2016-01-03
  • 2017-08-09
  • 2017-09-18
  • 1970-01-01
  • 2021-07-23
相关资源
最近更新 更多