Angular 4 - 如何进行批量http同步请求
Angular 4 - How to make bulk http syncronous requests
我的 Angular 4 应用程序中有一个用于上传数据的处方集。此数据来自 JSON 个元素的数组,我循环遍历它以通过可观察对象发出 HTTP PUT 请求。
如果要上传一小部分元素,一切正常,但有时输入可能超过 1000 个元素。
因为我使用的是可观察对象,所以所有请求都是以同步方式发出的,所以是在同一时间。如果元素数量足够大,这会使后端崩溃。
我需要一个接一个地发出 HTTP 请求,但我不知道该怎么做。 ¿你能帮我吗?
服务功能:
putIp(ip, data): any {
const url = `${this.IpUrl}/${ip}`;
return this.authHttp.put(url, data, {headers: this.headers});}
组件函数:
publishIps(): void {
console.log("Publishing Ips")
for (let _i = 0; _i < this.ipsInTable.length; _i++) {
this.ipsInTable[_i].treated = true;
this.ipService.putIp(this.ipsInTable[_i].id, this.ipsInTable[_i].json)
.catch(err => {
this.ipsInTable[_i].result = false;
this.ipsInTable[_i].message = "Error";
return Observable.throw(this.errorHandler(err));
})
.subscribe((data) => {
// Doing some stuff
});
}
}
我会调整后端以接受一组对象。然后你只做一个请求。
如果这不是一个选项,并且您希望一次提交一个请求,那么您可以使用控制器代码的另一种方法:
publishIp(_i: int): void {
if (_i < this.ipsInTable.length) {
this.ipsInTable[_i].treated = true;
this.ipService.putIp(this.ipsInTable[_i].id, this.ipsInTable[_i].json)
.catch(err => {
this.ipsInTable[_i].result = false;
this.ipsInTable[_i].message = "Error";
return Observable.throw(this.errorHandler(err));
})
.subscribe((data) => {
_i++;
publishIp(_i);
// Doing some stuff
});
}
}
publishIps(): void {
console.log("Publishing Ips");
publishIp(0);
}
免责声明: 我只是将其输入到 Whosebug 中。您可能需要更正一些拼写错误。
您可以使用带油门的 mergeMap
。代码看起来像这样:
Observable
// From takes an array and breaks each item into an individual event
.from(arrayOfItems)
// A mergeMap takes an event and converts it into a new observable
// in this case -- a request. The second argument is how many items to
// allow in flight at once -- you can limit your network activity here.
.mergeMap(item => saveItemObservable(item), requestLimit)
// Will emit an event once all of the above requests have completed
.toArray()
// You will have an array of response results.
.subscribe(arrayOfResults => { ... });
如果您使用的是较新版本的 RxJS,它将如下所示:
// You will need the correct imports:
// i.e import { from } from 'rxjs/observable/from';
// i.e. import { mergeMap, toArray } from 'rxjs/operators';
// From takes an array and breaks each item into an individual event
from(arrayOfItems).pipe(
// A mergeMap takes an event and converts it into a new observable
// in this case -- a request. The second argument is how many items to
// allow in flight at once -- you can limit your network activity here.
mergeMap(item => saveItemObservable(item), requestLimit),
// Will emit an event once all of the above requests have completed
toArray()
)
// You will have an array of response results.
.subscribe(arrayOfResults => { ... });
如果您删除 toArray
您将在订阅中为每个已完成的事件获得一个事件。
我的 Angular 4 应用程序中有一个用于上传数据的处方集。此数据来自 JSON 个元素的数组,我循环遍历它以通过可观察对象发出 HTTP PUT 请求。
如果要上传一小部分元素,一切正常,但有时输入可能超过 1000 个元素。
因为我使用的是可观察对象,所以所有请求都是以同步方式发出的,所以是在同一时间。如果元素数量足够大,这会使后端崩溃。
我需要一个接一个地发出 HTTP 请求,但我不知道该怎么做。 ¿你能帮我吗?
服务功能:
putIp(ip, data): any {
const url = `${this.IpUrl}/${ip}`;
return this.authHttp.put(url, data, {headers: this.headers});}
组件函数:
publishIps(): void {
console.log("Publishing Ips")
for (let _i = 0; _i < this.ipsInTable.length; _i++) {
this.ipsInTable[_i].treated = true;
this.ipService.putIp(this.ipsInTable[_i].id, this.ipsInTable[_i].json)
.catch(err => {
this.ipsInTable[_i].result = false;
this.ipsInTable[_i].message = "Error";
return Observable.throw(this.errorHandler(err));
})
.subscribe((data) => {
// Doing some stuff
});
}
}
我会调整后端以接受一组对象。然后你只做一个请求。
如果这不是一个选项,并且您希望一次提交一个请求,那么您可以使用控制器代码的另一种方法:
publishIp(_i: int): void {
if (_i < this.ipsInTable.length) {
this.ipsInTable[_i].treated = true;
this.ipService.putIp(this.ipsInTable[_i].id, this.ipsInTable[_i].json)
.catch(err => {
this.ipsInTable[_i].result = false;
this.ipsInTable[_i].message = "Error";
return Observable.throw(this.errorHandler(err));
})
.subscribe((data) => {
_i++;
publishIp(_i);
// Doing some stuff
});
}
}
publishIps(): void {
console.log("Publishing Ips");
publishIp(0);
}
免责声明: 我只是将其输入到 Whosebug 中。您可能需要更正一些拼写错误。
您可以使用带油门的 mergeMap
。代码看起来像这样:
Observable
// From takes an array and breaks each item into an individual event
.from(arrayOfItems)
// A mergeMap takes an event and converts it into a new observable
// in this case -- a request. The second argument is how many items to
// allow in flight at once -- you can limit your network activity here.
.mergeMap(item => saveItemObservable(item), requestLimit)
// Will emit an event once all of the above requests have completed
.toArray()
// You will have an array of response results.
.subscribe(arrayOfResults => { ... });
如果您使用的是较新版本的 RxJS,它将如下所示:
// You will need the correct imports:
// i.e import { from } from 'rxjs/observable/from';
// i.e. import { mergeMap, toArray } from 'rxjs/operators';
// From takes an array and breaks each item into an individual event
from(arrayOfItems).pipe(
// A mergeMap takes an event and converts it into a new observable
// in this case -- a request. The second argument is how many items to
// allow in flight at once -- you can limit your network activity here.
mergeMap(item => saveItemObservable(item), requestLimit),
// Will emit an event once all of the above requests have completed
toArray()
)
// You will have an array of response results.
.subscribe(arrayOfResults => { ... });
如果您删除 toArray
您将在订阅中为每个已完成的事件获得一个事件。