我目前正从角度1.x迁移到角度2。该应用程序目前遵循John Papa的风格指南Return a Promise from Data Calls。
activate();
function activate() {
/**
* Step 1
* Ask the getAvengers function for the
* avenger data and wait for the promise
*/
return getAvengers().then(function() {
/**
* Step 4
* Perform an action on resolve of final promise
*/
logger.info('Activated Avengers View');
});
}
function getAvengers() {
/**
* Step 2
* Ask the data service for the data and wait
* for the promise
*/
return dataservice.getAvengers()
.then(function(data) {
/**
* Step 3
* set the data and resolve the promise
*/
vm.avengers = data;
return vm.avengers;
});
}
我如何用Observables做同样的事情?有了承诺,我可以在多个函数中编写.then()
并返回它,这样调用函数也会等待承诺。但有了可观察性,做正确的事情是什么?
我应该在哪里订阅,我应该在哪里映射值并返回可观察量?
答案 0 :(得分:1)
map
,并通过这样做来创建新的Observable
。
getAvengers.map(avengers => avengers.forEach(a => a.kill))
将创建一个可观察的死亡复仇者。然后你可以订阅这个observable来调用死亡复仇者的方法。
subscribe更像then
,因为它只是等待数据调用传递给它的方法。但是订阅会触发可观察对象,这意味着如果您只是致电getAvengers()
(假设getAvengers
返回Observable
),您将获得Observable
,以触发请求必须subscribe
。
两次调用subscribe
会触发Observable
两次,这意味着如果您根据http请求在subscribe
上调用Observable
,则请求将完成两次。
因此,您可以使用带有observable的缓存来处理此问题,但文档将能够指导您完成此操作。
答案 1 :(得分:1)
假设您的函数在执行http请求之前将调用其中的多个函数。
function A() {
B().subscribe();
}
function B() {
return C().map();
}
function C() {
return D().map();
}
function D() {
// call http reuest and return data
}
调用者函数将执行实际订阅,而参与的所有其他函数将只是映射数据。
来到你的代码,你将不得不这样修改:
activate();
function activate() {
/**
* Step 1
* Ask the getAvengers function for the
* avenger data and wait for the promise
*/
return getAvengers().subscribe(
(data) => {
// handle your result data
logger.info('Activated Avengers View');
});
}
function getAvengers() {
/**
* Step 2
* Ask the data service for the data and wait
* for the promise
*/
return dataservice.getAvengers()
.map((data) => {
/**
* Step 3
* set the data and resolve the Observable
*/
vm.avengers = data;
return vm.avengers;
});
}
答案 2 :(得分:1)
使用promises时使用.then()
,使用Observables,你有足够多的operators可以组合多个observable,创建副作用,修改初始observable发出的值等等。{{1如@Supamiu所解释的那样是所有这些运算符的一个例子。
Observable不会按原样执行任何操作,它们定义数据流,它只是触发数据广播过程的订阅。
大部分时间你都不需要map
,你可以使用subscribe
管道为你做角度处理。例如:
组件:
async
模板:
this.avengers$=this.dataservice.getAvengers().do(()=>console.log("Avengers fetched");
它定义数据流的事实允许您对创建非常复杂的流的事件做出反应,而没有太多的副作用或努力。
组件:
<span *ngFor="avenger of avengers$|async">{{avenger.name}}</span>
模板:
avengerClick$ = new Subject<mouseEvent>();
constructor(){
let initialAvengers = this.dataservice.getAvengers().do(()=>console.log("Avengers fetched").switchMap(avangers);
this.avengers$ = Observable.merge(
initialAvengers,
this.avengerClick.switchMap(()=>this.dataservice.createAvenger()) // let's say this.dataservice.createAvenger() returns the new list of avengers
)
}