我正在尝试使用switchMap取消Angular2中以前的任何http调用。 代码基本上是
var run = ():Observable<any> => {
var url = 'http://...'
return this._http.get(url)
.map(result => {
return var xmlData:string = result.text()
});
}
function pollTasks() {
return Observable.of(1)
.switchMap(() => run())
.map(res => res)
}
// caller can do subscription and store it as a handle:
let tasksSubscription =
pollTasks()
.subscribe(data => {
console.log('aa'+data)
});
所以我连续几次调用整个源代码并收到几个回复(即:aa + data)
我的印象是switchMap应取消之前的通话。
答案 0 :(得分:21)
请求需要源自相同的基础流。这是一个工厂函数,它将创建一个应该做你想做的http服务实例:
function httpService(url) {
// httpRequest$ stream that allows us to push new requests
const httpRequest$ = new Rx.Subject();
// httpResponse$ stream that allows clients of the httpService
// to handle our responses (fetch here can be replaced with whatever
// http library you're using).
const httpResponse$ = httpRequest$
.switchMap(() => fetch(url));
// Expose a single method get() that pushes a new
// request onto the httpRequest stream. Expose the
// httpResponse$ stream to handle responses.
return {
get: () => httpRequest$.next(),
httpResponse$
};
}
现在客户端代码可以使用这样的服务:
const http = httpService('http://my.api.com/resource');
// Subscribe to any responses
http.httpResponse$.subscribe(resp => console.log(resp));
// Call http.get() a bunch of times: should only get one log!!
http.get();
http.get();
http.get();
答案 1 :(得分:7)
constructor(private _http:Http, private appStore:AppStore) {
this.httpRequest$ = new Subject();
this.httpRequest$
.map(v=> {
return v;
})
.switchMap((v:any):any => {
console.log(v);
if (v.id==-1||v.id=='-1')
return 'bye, cancel all pending network calls';
return this._http.get('example.com)
.map(result => {
var xmlData:string = result.text()
});
}).share()
.subscribe(e => {
})
...
并推送数据:
this.httpRequest$.next({id: busId});
这很好用,我现在可以有一个服务,我可以管理所有网络电话,也可以取消之前的电话......
见下图,随着新来电的进入,之前的电话被取消。 请注意我如何设置慢速网络,延迟时间为4秒,以便提供所有正常工作...
答案 2 :(得分:3)
我认为当您使用switchMap
运算符时,您只能取消当前数据流中的请求。我的意思是在同一个可观察链上发生的事件......
如果您多次调用pollTasks
方法,则无法取消之前的请求,因为它们不在同一数据流中...每次调用时都会创建一个可观察链方法。
我不知道你是如何触发执行请求的。
如果您想每500毫秒执行一次请求,可以试试这个:
pollTasks() {
return Observable.interval(500)
.switchMap(() => run())
.map(res => res.json());
}
在这种情况下,如果在500ms之后有正在进行的请求,它们将被取消以执行新的
使用此方法,您只需要调用pollTasks
方法。
您还可以根据用户事件触发异步处理链。例如,在输入中填充字符时:
var control = new Control();
// The control is attached to an input using the ngFormControl directive
control.valueChanges.switchMap(() => run())
.map(res => res.json())
.subscribe(...);
有人建议在DOM事件(fromEvent
)
请看这个链接:
答案 3 :(得分:0)
您可以使用主题但如果您这样做,则必须管理订阅和发布。如果你只想要一个返回Observable的方法来取消一个时间间隔内的请求,我就是这样做的:
observer: Observer<CustomObject>;
debug = 0;
myFunction(someValue) {
this.observable = new Observable<CustomObject>(observer => {
if (!this.observer) {
this.observer = observer;
}
// we simulate http response time
setTimeout(() => {
this.observer.next(someValue);
this.debug++;
}, 1000);
})
.debounceTime(3000) // We cancel request withing 3s interval and take only the last one
.switchMap(fn)
.do(() => {
console.log("debug", this.debug);
});
}
一直使用相同的观察者让我们根据我们想要的任何方式取消请求(debounceTime,distinctUntilChanged,...)。