当我尝试通过Angular 4中的http服务发出多个http请求时,
之前的请求在Chrome中被取消(但它们到达服务器)。
例:
const obs1 = this.http.get(`${API_URL}/transitions`);
const obs2 = this.http.get(`${API_URL}/states`);
obs1.subscribe();
obs2.subscribe(); // this will cancel obs1's http request
但如果我更换 .subscribe()
至 .publish().connect()
像上面一样,它会正常工作(没有取消)
const obs1 = this.http.get(`${API_URL}/transitions`);
const obs2 = this.http.get(`${API_URL}/states`);
obs1.publish().connect();
obs2.publish().connect();
或者如果我合并两个 Observables
到一个,然后像上面那样订阅,它也将正常工作
const obs1 = this.http.get(`${API_URL}/transitions`);
const obs2 = this.http.get(`${API_URL}/states`);
Observable.merge(obs1, obs2).subscribe()
为什么我会面对这种行为?我需要了解,而不是绕过。 我该如何提出一系列请求 无 合并,分叉等?
我发现了这种行为的潜在原因。
谢谢 https://github.com/ghetolay 和 https://github.com/dklmuc
我们发现angular会取消非常快速的http请求,而不需要任何回调。所以,你必须在订阅中传递onNext
从 https://github.com/ghetolay:
好吧,我认为这是竞争条件
它总是会在拆解时调用xhr.abort()
如果浏览器仍认为连接已打开,它将关闭它,否则可能什么都不做
所以当你对响应进行非常快速的处理时(比如没有回调真的很快),它可能会中止仍然被认为是开放的连接
这个工作正常:
for (let i = 1; i < 50; i++) {
http.get(`https://swapi.co/api/people/${i}`).subscribe((result) => {
console.log(i, result);
});
}
我发现了这种行为的潜在原因。
谢谢 https://github.com/ghetolay 和 https://github.com/dklmuc
我们发现angular会取消非常快速的http请求,而不需要任何回调。所以,你必须在订阅中传递onNext
从 https://github.com/ghetolay:
好吧,我认为这是竞争条件
它总是会在拆解时调用xhr.abort()
如果浏览器仍认为连接已打开,它将关闭它,否则可能什么都不做
所以当你对响应进行非常快速的处理时(比如没有回调真的很快),它可能会中止仍然被认为是开放的连接
这个工作正常:
for (let i = 1; i < 50; i++) {
http.get(`https://swapi.co/api/people/${i}`).subscribe((result) => {
console.log(i, result);
});
}
这与被观察者被取消有关,虽然我必须承认我不知道你面临的问题的根本原因。
我使用ngrx / effects模块遇到了类似的问题。操作处理程序使用ngrx switch map operator向服务发出请求。除最后一个请求外的所有请求都将被取消将其更改为合并映射修复了问题。
以下是代码
@Effect()
loadSomeData$: Observable<Action> = this.actions$
.ofType(SomeActions.Load_Data)
.mergeMap((id) =>
this.someService.getSomething(id)
.map((someEntity) => new SomeActions.LoadDataSuccess(someEntity)
).catch((x, y) => {
console.error('Error occured');
return Observable.of(new SomeActions.LoadDataFailed(id));
}
));
在这里复制ngrx的相关部分。
https://www.learnrxjs.io/operators/transformation/switchmap.html
switchMap与其他展平运算符的主要区别在于取消效果。在每次发射时,前一个内部observable(您提供的函数的结果)被取消,并且新的observable被订阅。您可以通过短语切换到新的observable来记住这一点。
对我来说问题是因为一个空的可观察者。
我在用 Observable.forkJoin
在可观察的列表上。
解: 我需要给我 Observable.of()
一个值: Observable.of(null)