开发者问题收集

从异步函数返回可观察对象

2019-08-13
8974

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

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

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

基于: 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个回答

在您的实现中, create 返回一个承诺,因为正如您所指出的那样,它需要 async 工作。如果这是事实,那么您必须修改调用 create 的上下文:只需将调用函数也设为 async ,并在调用 create 之前添加 awaitawait create(...)

或者,如果您无论如何都想返回可观察对象,则必须停止 await ing db.collection().add() 并在 create 之前删除 async 。然后,您可以直接返回可观察对象,并且在 db.collection().add().then 函数中,您可以使用 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 ,而后者又有一个 .then ,依此类推 - 这就是 Promise 的定义方式。

B M
2019-08-13