从异步函数返回 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
之前添加await
:await create(...)
。
作为替代方案,如果你想无论如何都返回一个 observable,你必须停止 await
ing 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
等等 - 这就是 Promise
s 的定义方式。
【讨论】:
是的,后者对我有用,简单的解决方案谢谢。 你也可以让内部函数异步return new Observable(async subscriber =>
这样也行,是的。就我个人而言,我觉得如果不使用它,不要从回调中返回 Promise
会更干净,但两者都是有效的解决方案。以上是关于从异步函数返回 observable的主要内容,如果未能解决你的问题,请参考以下文章
在异步函数内部,从回调函数返回值返回 Promise(undefined) [重复]
在异步函数内部,从回调函数返回值返回 Promise(undefined) [重复]
如何从Objective-C中的异步内部函数内部返回外部函数