return 像 returning promises 一样可以被调用者函数观察到
return observable to the caller function like returning promises
我目前正在从 angular 1.x 迁移到 angular 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 做同样的事情?有了 promise,我可以在多个函数中编写 .then()
和 return 以便调用函数也将等待 promise。但是对于 observable,正确的做法是什么?
我到底应该在哪里订阅,我应该在哪里映射值和 return 可观察值?
map
应该在你想修改发送的数据时使用,这样做会创建一个新的 Observable
.
示例:
getAvengers.map(avengers => avengers.forEach(a => a.kill))
将创建一个已死复仇者的可观察对象。然后你可以订阅这个 observable 来调用死去的复仇者的方法。
subscribe 更像 then
因为它只是等待数据调用传递给它的方法。但是 subscribe 会触发 observable,这意味着如果你简单地调用 getAvengers()
(假设 getAvengers
returns 一个 Observable
)你会得到一个 Observable
,到触发你必须 subscribe
.
的请求
小心:
调用subscribe
两次会触发Observable
两次,也就是说如果你在一个基于http请求的Observable
上调用subscribe
,请求就会完成两次。
因此,您可以使用带有可观察对象的缓存来处理此问题,但文档将能够指导您完成此操作。
假设您的函数将在执行 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;
});
}
在使用 promises 时,你使用 .then()
,使用 Observables,你有很多 operators 可以让你组合多个 observables,产生副作用,修改初始 observable 发出的值等。map
正如@Supamiu 所解释的那样是所有这些运算符的一个例子。
Observables 不会按原样做任何事情,它们定义了一个数据流,它只是触发数据广播过程的订阅。
异步管道
大多数时候你并不需要使用 subscribe
,你可以让 angular 为你处理,使用 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
)
}
模板:
<span *ngFor="avenger of avengers$|async">{{avenger.name}}</span>
<span (click)="avengerClick$.next($event)">Create an avenger</span>
我目前正在从 angular 1.x 迁移到 angular 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 做同样的事情?有了 promise,我可以在多个函数中编写 .then()
和 return 以便调用函数也将等待 promise。但是对于 observable,正确的做法是什么?
我到底应该在哪里订阅,我应该在哪里映射值和 return 可观察值?
map
应该在你想修改发送的数据时使用,这样做会创建一个新的 Observable
.
示例:
getAvengers.map(avengers => avengers.forEach(a => a.kill))
将创建一个已死复仇者的可观察对象。然后你可以订阅这个 observable 来调用死去的复仇者的方法。
subscribe 更像 then
因为它只是等待数据调用传递给它的方法。但是 subscribe 会触发 observable,这意味着如果你简单地调用 getAvengers()
(假设 getAvengers
returns 一个 Observable
)你会得到一个 Observable
,到触发你必须 subscribe
.
小心:
调用subscribe
两次会触发Observable
两次,也就是说如果你在一个基于http请求的Observable
上调用subscribe
,请求就会完成两次。
因此,您可以使用带有可观察对象的缓存来处理此问题,但文档将能够指导您完成此操作。
假设您的函数将在执行 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;
});
}
在使用 promises 时,你使用 .then()
,使用 Observables,你有很多 operators 可以让你组合多个 observables,产生副作用,修改初始 observable 发出的值等。map
正如@Supamiu 所解释的那样是所有这些运算符的一个例子。
Observables 不会按原样做任何事情,它们定义了一个数据流,它只是触发数据广播过程的订阅。
异步管道
大多数时候你并不需要使用 subscribe
,你可以让 angular 为你处理,使用 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
)
}
模板:
<span *ngFor="avenger of avengers$|async">{{avenger.name}}</span>
<span (click)="avengerClick$.next($event)">Create an avenger</span>