最近,我的一位同事在Angular 6应用程序的Subscription中实现了回调,如下所示:
callDoSomething() {
this.doSomething(() => {
// logic from callback
});
}
public doSomething(callback: any) {
this.http.get('/api/doSomething').subscribe(data => {
// do something with data
if (callback) {
callback();
}
}, error => {
// do something with error
});
}
我认为最好用RxJS Observable解决此“问题”。但是在实现/重构代码后,它似乎并不是更好的解决方案。该代码现在看起来更加复杂。是否有必要将管道投放到承诺中并以可观察的方式返回?
import { Observable, of as observableOf, from as observableFrom } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
callDoSomething() {
this.doSomething().subscribe((result) => {
if (result) {
// logic from callback
}
});
}
public doSomething() {
let promise = this.http.get('/api/doSomething').pipe(
map(data => {
// do something with data
return observableOf(true);
}),
catchError((error) => {
// do something with error
return observableOf(false);
})
).toPromise()
return observableFrom(promise);
}
是否有更好的方法来解决Observables的问题?还是我的同事有权使用简单的回调?
答案 0 :(得分:1)
您无需强制转换为Promise
,然后再次强制转换为Observable
。还要看一下map
函数。为什么从中返回true
? map
函数用于更改即将到来的数据,然后再传递已更改的数据。
public doSomething() {
let observable= this.http.get('/api/doSomething').pipe(
map(data => {
// do something with data
return observableOf(true);
}),
catchError((error) => {
// do something with error
return observableOf(false);
}));
return observable;
}
答案 1 :(得分:1)
恕我直言,回调是最简单的解决方案。完整的处理程序可能是一个更好的地方。如果您想使用可观察变量,那么我会坚持使用流语义。
如果您的目标是处理成功案例,但又不想从函数中获取数据,则可以返回一个空的,完整的可观察值。如果发生错误,您可以让它通过,也可以将其替换为以错误结尾的空的可观察对象。它类似于observable.of(true / false)
,但是依赖于流语义而不是任意值。
doSomething() {
return this.http.get('/api/doSomething').pipe(
flatMap(data => {
// do something with data
return empty();
}),
catchError((error) => {
// do something with error
return throwError(error); //instead of error pass whatever you like
})
);
}
callDoSomething() {
this.doSomething()
.subscribe(
undefined, //we don't handle data
undefined, //we don't handle errors
() => {// logic from callback}
);
}
如您所见,它的代码仍然比回调解决方案多得多。但是,如果有一天添加了错误回调,这可能是一个有趣的选择。可观察到的解决方案的好处是:没有。