Angular 2 - 直接从 Observable 返回数据
Posted
技术标签:
【中文标题】Angular 2 - 直接从 Observable 返回数据【英文标题】:Angular 2 - Return data directly from an Observable 【发布时间】:2016-10-18 10:23:30 【问题描述】:我一直在努力解决这个问题,但我能够阅读的任何文档都无法回答我的问题。
我有一个服务直接与 API 对话并返回一个可观察的事件,在正常情况下我会订阅并使用数据做我想做的事情,但是在使用来自 restful 服务的请求的辅助服务中,我需要能够从请求中返回值。
getSomething()
return this._restService.addRequest('object', 'method').run()
.subscribe(
res =>
res;
,
err =>
console.error(err);
);
returnSomething()
return this.getSomething();
在上面的快速示例中,我想知道是否有任何方法可以在returnSomething()
中从getSomething()
返回res
。如果以这种方式无法实现,还有什么替代方法?我要补充一点,_restService 非常依赖,我真的不想开始搞砸了。
【问题讨论】:
你在哪里使用returnSomething()
?您知道这是一个异步操作,因此您无法立即“获得”结果。您也许可以在returnSomething()
中订阅(res)
,但我不知道这是否实用。
上面的示例将包含在一个服务中,并且对该方法的调用将在多个组件中,这就是为什么我只想返回 res
值,因为它会节省很多一点代码。我还需要能够比较两种或多种类似方法的结果。
【参考方案1】:
由于 http 调用等是异步的,因此您会得到一个 Observable
而不是返回的同步值。您必须订阅它,并在其中的回调中获取数据。没有办法解决这个问题。
一种选择是将您的逻辑放在subscribe
调用中
getSomething()
return this._restService.addRequest('object', 'method').run()
.subscribe(
res =>
// do something here
res;
,
err =>
console.error(err);
);
但我喜欢这样做的方式是添加一个回调,从外部注入逻辑(可能是一个组件,也可能是另一个服务):
getSomething(callback: (data) => void)
return this._restService.addRequest('object', 'method').run()
.subscribe(
res =>
callback(res);
,
err =>
console.error(err);
);
在您的组件中或任何地方:
this._yourService.getSomething((data) =>
// do something here
console.log(data);
);
【讨论】:
绝对是一种思考使用服务的新方式,结果证明这正是我们所需要的! 我来到这里大概是因为 Observable 关键字。我需要做类似的事情。什么类型的服务有方法 .run()?我不能在常规的 Angular 2 http 服务上使用它。谢谢 花了大约几个小时来找出错误。谢谢你的回答。 主题行为如何【参考方案2】:我遇到了类似的问题。我的解决方案是使用 .toPromise() 将 observable 转换为 promise(并使用 async - await 来返回它并捕获错误)。您可以将您的代码转换为:
async getSomething()
try
return await this._restService.addRequest('object', 'method').run().toPromise()
catch (err)
console.error(err);
【讨论】:
这不是最初问题的解决方案。您不会以这种方式返回数据,而是返回Promise
,并且您仍然必须“订阅”它(使用 then
)才能获得最终数据。【参考方案3】:
我自己没有使用过这个,但我相信理论上它应该可以工作(:
// service.ts
getSomething()
let subject: Subject = new Subject();
this._restService.addRequest('object', 'method').run()
.subscribe(subject);
return subject;
// this can be removed (;
returnSomething()
return this.getSomething();
// component.ts
ngOnInit()
this.service.returnSomething()
.subscribe(res => console.log(res), err => console.log(err));
查看subject docs 了解更多信息。您可以使用不同类型的主题,例如 BehaviorSubject 具有您可以访问的 value
属性...
ngOnInit()
// if you use BehaviorSubject
this.service.returnSomething().value
这是working plunker...
【讨论】:
这行不通,因为主题在您从订阅中获取数据之前已返回。 @rinukkusu 是的,对于初始值,应该在之后工作。您可以在订阅 observable 之前为 BehaviourSubject 设置初始值...或.filter(Boolean)
。 ..以上是关于Angular 2 - 直接从 Observable 返回数据的主要内容,如果未能解决你的问题,请参考以下文章
Angular RxJS入门笔记 (Observable可观察对象Subscribe订阅Observer观察者Subscription对象)
html 使用AJAX POST请求来调用控制器操作(在页面加载时和在下拉列表中选择项目时),获取返回的布尔值,设置observabl
如何直接从您的 Angular 项目中调用 Firebase Cloud Function