从异步函数返回 observable

Posted

技术标签:

【中文标题】从异步函数返回 observable【英文标题】:Return observable from async function 【发布时间】:2019-12-19 18:16:10 【问题描述】:

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

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

背景: 我正在尝试声明一个创建 Firestore 文档的函数,然后使用 collection().add() 返回的 DocumentReference 上的 onSnapshot() 函数返回带有文档数据的 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,我需要该函数返回一个 observable。

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

// ... 

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

【问题讨论】:

你能详细说明你的代码到底有什么问题吗?您是否有任何弹出的错误消息?你如何使用create 方法?预期行为与实际行为有何不同? 【参考方案1】:

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

作为替代方案,如果你想无论如何都返回一个 observable,你必须停止 awaiting db.collection().add() 并在 create 之前删除 async。然后你可以直接返回 observable,在 db.collection().add().then 函数中你可以用 doc.data() 更新 observable:

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 等等 - 这就是 Promises 的定义方式。

【讨论】:

是的,后者对我有用,简单的解决方案谢谢。 你也可以让内部函数异步return new Observable(async subscriber => 这样也行,是的。就我个人而言,我觉得如果不使用它,不要从回调中返回 Promise 会更干净,但两者都是有效的解决方案。

以上是关于从异步函数返回 observable的主要内容,如果未能解决你的问题,请参考以下文章

在异步函数内部,从回调函数返回值返回 Promise(undefined) [重复]

在异步函数内部,从回调函数返回值返回 Promise(undefined) [重复]

如何从Objective-C中的异步内部函数内部返回外部函数

如何从Objective-C中的异步内部函数内部返回外部函数

如何从异步调用返回响应

如何从异步调用返回响应