从异步函数返回可观察到的值

时间:2019-08-13 08:02:09

标签: javascript firebase promise async-await observable

TLDR; 我有一个Promise collection().add(),它解析为一个对象DocumentReference,该对象具有发出数据的侦听器函数onSnapshot()

我需要返回一个Observable,在订阅时,它会调用Promise,在已解析的对象上订阅侦听器功能,并将值从侦听器广播到subscriber.next()

上下文: 我正在尝试声明一个函数,该函数创建一个Firestore文档,然后使用onSnapshot()返回的DocumentReference上的collection().add()函数,返回一个包含文档数据的Observable。

基于:https://github.com/EddyVerbruggen/nativescript-plugin-firebase/blob/f6972433dea48bf1d342a6e4ef7f955dff341837/demo-ng/app/item/items.component.ts#L175-L185

async create(project) {
    const ref = await this.db.collection('projects').add(project);
    return new Observable(subscriber => {
        ref.onSnapshot(doc => {
            // ...
            subscriber.next(doc.data());
        });
    });
}

当前行为: async/await始终返回Promise,我需要该函数返回可观察值。

预期:我需要从ref.onSnapshot()回调(在本例中为doc.data())中获取一部分数据,以在模板中使用它,例如

// ... 

this.service.create(project).subscribe(project => console.log(project));

1 个答案:

答案 0 :(得分:3)

在您的实现中,create返回一个诺言,因为正如您指出的那样,它需要工作async。如果这是事实,那么您必须修改上下文调用create:只需简单地创建调用函数async,并在调用await之前添加create:{{ 1}}。

或者,如果您无论如何要返回一个可观察值,则必须停止await create(...)进入await并删除db.collection().add()之前的async。然后,您可以直接返回可观测对象,并且可以在create的{​​{1}}函数内部使用.then更新可观测对象:

db.collection().add()

请注意,doc.data()只是处理create(project) { return new Observable(subscriber => { this.db.collection('projects').add(project) .then(ref => { ref.onSnapshot(doc => { // ... subscriber.next(doc.data()); }); }); }); } 的一种方法。更经典的方法是在其await上附加一个回调。请注意,Promise再次返回.then,它又具有.then,依此类推-这就是Promise的定义方式。