【问题标题】:return an observable from a finalize method on observable从 observable 上的 finalize 方法返回一个 observable
【发布时间】:2018-09-22 17:17:10
【问题描述】:

具体情况是这样的: AngularFirebase 文档说,为了从上传的文件中获取下载 URL,您需要这样做:

const task = this.storage.upload(filePath, file);

// observe percentage changes
// get notified when the download URL is available
task.snapshotChanges().pipe(
    finalize(() => this.downloadURL = fileRef.getDownloadURL() )
 )
.subscribe();
}

现在,我有一个上传方法,我想从它返回一个可观察的字符串。我的方法签名看起来像:

upload(file :File) :Observable<string> {

......

}

我试过这样做:

return <Observable<string>>task.snapshotChanges().pipe(
        finalize(() => {
            const url = fileRef.getDownloadURL();
            console.log('download url is ',url);
            return url;
        })
    );

但这不起作用,因为原始 observable 中还有其他类型的快照更改元素。

现在我的问题是,如何使用示例中的代码有效地返回我想要的类型

【问题讨论】:

  • 只需删除subscribe,然后返回您所拥有的
  • 那行不通。我更新了问题
  • 对不起,我的错。添加(在finalize 之后)map(() =&gt; fileRef.getDownloadURL())。不确定你从哪里得到fileRef,但map 函数将转换 Observable 发出的值
  • 触发次数过多。这工作stackblitz.com/edit/typescript-nqcr4w 但丑陋

标签: angular firebase rxjs


【解决方案1】:

如文档中所述,finalize...

返回一个镜像源 Observable 的 Observable,但会在源因完成或错误终止时调用指定函数。

也就是说,你不能用传递的函数改变 Observable 类型。

相反,您可以结合使用 last 运算符和 map 运算符来获取映射到所需属性的最后一个值的通知。它看起来像这样:

return <Observable<string>>task.snapshotChanges().pipe(
        last(),
        map(() => {
            const url = fileRef.getDownloadURL();
            console.log('download url is ',url);
            return url;
        })
    );

【讨论】:

  • 这非常好,几乎可以工作,除了fileRef.getDownloadURL() 本身返回一个可观察对象!所以它最终成为 ovservable>
  • 好的,应该没问题;只需将map 替换为mergeMap ;-)
  • 好主意,但要小心,如果您的源 observable 尚未发出值,它会引发错误!
  • 非常感谢。不过对last 有点怀疑。 rxjs 怎么知道last 实际上是last?是基于观察者的complete方法吗?
【解决方案2】:

我有同样的问题,这是我的解决方案

return <Observable<string>>task
      .snapshotChanges()
      .pipe(
        last(),
        flatMap(
          () => {
            return fileRef.getDownloadURL().pipe(
              map((url) => {
                return url;
              })
            );
          }
        )
      );

【讨论】:

  • 欢迎来到 SO。虽然这段代码 sn-p 可能是解决方案,但包含解释确实有助于提高帖子的质量。请记住,您正在为将来的读者回答问题,而这些人可能不知道您的代码建议的原因。详情请查看how-to-answer
猜你喜欢
  • 1970-01-01
  • 2020-10-10
  • 2017-03-29
  • 2021-11-07
  • 2020-06-01
  • 2021-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多