如何 运行 http 将请求置于循环中并获取每个单独请求的状态
How to run http put request in a loop and get status of every individual request
我有一个对象数组,它的每个对象都需要通过 put http 请求在数据库中更新。
[
{id: "3e81731f-e3b4-405d-a5ca-bef52c1b036a", date_created: "2019-07-24T15:55:31.372460Z", date_modified: "2020-07-13T03:25:02.720870Z", einsight_uuid: "d15176ab-ecf8-dba1-e040-10ac316407fa", attributes: {…}},
{id: "4707bff2-8265-456f-a4d4-ca1134d85620", date_created: "2019-07-24T15:55:31.372460Z", date_modified: "2020-07-13T03:25:06.238019Z", einsight_uuid: "fcda4259-3ecb-4566-85b0-5b6d5c7647f6", attributes: {…}}
{id: "d29a3340-04b6-431b-8671-a0f0d25a9b51", date_created: "2019-07-24T15:55:31.3724", date_modified: "2020-07-13T03:25:06.238019Z", einsight_uuid: "fcda4259-3ecb-4566-85b0-5b6d5c7647f6", attributes: {…}}
]
如何调用 api 将每条记录保存在数组中。在循环中调用 Api 是一个简单的选择,但还不够。我想记录每个回复。他们中有多少人成功或失败了。
在 angular 或 rxjs
中是否有任何可用的已知最佳实践来执行此类操作
您可以使用 rxjs concat,但 concat 会在 observable 抛出错误时停止,因此您可以使用 catchError return 一个新的 observable
import { of ,concat} from 'rxjs';
....
data = [
{id:1},
{id:2},
{id:-1},
{id:2},
]
constructor(private http:HttpClient){
let httpReqs = this.data
.map(i =>
this.http.put(`https://jsonplaceholder.typicode.com/posts/${i.id}`,{})
.pipe(catchError(err => of({err})))
);
concat(...httpReqs).subscribe(console.log)
}
检查这个rxjs concat
您可以根据请求的数量和您的要求并行或顺序请求。
并行请求
使用 RxJS forkJoin
function with tap
and catchError
运算符。尝试以下
import { forkJoin, of, from } from 'rxjs';
import { tap, catchError, concatMap } from 'rxjs/operators';
putDataParallel() {
let success = 0; // <-- trivial counters
let errors = 0;
const reqs = this.urls.map(url => // <-- replate `this.urls` with your object array
this.http.put(url).pipe( // <-- replace `url` with your own PUT request
tap(_ => success++), // <-- count successful responses here
catchError(err => {
errors++; // <-- count errors here
return of(err); // <-- remember to return an observable from `catchError`
})
)
);
forkJoin(reqs).subscribe(
null, // <-- you could change response callback to your requirement
err => console.log(err),
() => console.log(`Success: ${success}\nErrors: ${errors}`),
);
}
顺序请求
对顺序数据流使用 RxJS from
function and concatMap
运算符。尝试以下
import { forkJoin, of, from } from 'rxjs';
import { tap, catchError, concatMap } from 'rxjs/operators';
putDataSequential() {
let success = 0; // <-- trivial counters
let errors = 0;
from(this.urls).pipe( // <-- replate `this.urls` with your object array
concatMap(url => {
return this.http.put(url).pipe( // <-- replace `url` with your own PUT request
tap(_ => success++), // <-- count successful responses here
catchError(err => {
errors++; // <-- count errors here
return of(err); // <-- remember to return an observable from `catchError`
})
)
})
).subscribe(
null, // <-- you could change response callback to your requirement
err => console.log(err),
() => console.log(`Success: ${success}\nErrors: ${errors}`),
);
}
无论错误或响应如何,这两种方法都将 运行 直到数组中的所有对象都完成。但是,如果您希望在出现错误时中断序列,请替换 catchError
运算符中的 return of(err);
语句以抛出 error
或 complete
通知。例如你可以使用 RxJS EMPTY
常量:return EMPTY;
.
我以普通计数器为例。您可以改为使用对象(例如)来记录 response/errors 的数量和 HTTP 请求的相应输入。
工作示例:Stackblitz
如您所见,每个项目都将使用 concateMap 进行处理,并且在发出 HTTP
请求后,每个项目 result
数组都会更新。
有多种方法,你可以达到这个结果。这是此处显示的方法之一。
items =[
{id: "3e81731f-e3b4-405d-a5ca-bef52c1b036a", name :'united', result:[]},
{id: "4707bff2-8265-456f-a4d4-ca1134d85620", name: 'ind', result:[]},
{id: "d29a3340-04b6-431b-8671-a0f0d25a9b51", name:'ru', result:[]},
{id: "xxx-xxxx-xxxx-xxxxx", name:'', result:[]}
]
from(this.items)
.pipe(
concatMap(item => this.ob2(item.name).pipe(
catchError(err=>of(err)),
tap(result =>{
if(result.length){
item.result = result;
}else{
// error scenario can be handled here
}
console.log('Updated each item', item)
})
))
).subscribe();
}
我有一个对象数组,它的每个对象都需要通过 put http 请求在数据库中更新。
[
{id: "3e81731f-e3b4-405d-a5ca-bef52c1b036a", date_created: "2019-07-24T15:55:31.372460Z", date_modified: "2020-07-13T03:25:02.720870Z", einsight_uuid: "d15176ab-ecf8-dba1-e040-10ac316407fa", attributes: {…}},
{id: "4707bff2-8265-456f-a4d4-ca1134d85620", date_created: "2019-07-24T15:55:31.372460Z", date_modified: "2020-07-13T03:25:06.238019Z", einsight_uuid: "fcda4259-3ecb-4566-85b0-5b6d5c7647f6", attributes: {…}}
{id: "d29a3340-04b6-431b-8671-a0f0d25a9b51", date_created: "2019-07-24T15:55:31.3724", date_modified: "2020-07-13T03:25:06.238019Z", einsight_uuid: "fcda4259-3ecb-4566-85b0-5b6d5c7647f6", attributes: {…}}
]
如何调用 api 将每条记录保存在数组中。在循环中调用 Api 是一个简单的选择,但还不够。我想记录每个回复。他们中有多少人成功或失败了。 在 angular 或 rxjs
中是否有任何可用的已知最佳实践来执行此类操作您可以使用 rxjs concat,但 concat 会在 observable 抛出错误时停止,因此您可以使用 catchError return 一个新的 observable
import { of ,concat} from 'rxjs';
....
data = [
{id:1},
{id:2},
{id:-1},
{id:2},
]
constructor(private http:HttpClient){
let httpReqs = this.data
.map(i =>
this.http.put(`https://jsonplaceholder.typicode.com/posts/${i.id}`,{})
.pipe(catchError(err => of({err})))
);
concat(...httpReqs).subscribe(console.log)
}
检查这个rxjs concat
您可以根据请求的数量和您的要求并行或顺序请求。
并行请求
使用 RxJS forkJoin
function with tap
and catchError
运算符。尝试以下
import { forkJoin, of, from } from 'rxjs';
import { tap, catchError, concatMap } from 'rxjs/operators';
putDataParallel() {
let success = 0; // <-- trivial counters
let errors = 0;
const reqs = this.urls.map(url => // <-- replate `this.urls` with your object array
this.http.put(url).pipe( // <-- replace `url` with your own PUT request
tap(_ => success++), // <-- count successful responses here
catchError(err => {
errors++; // <-- count errors here
return of(err); // <-- remember to return an observable from `catchError`
})
)
);
forkJoin(reqs).subscribe(
null, // <-- you could change response callback to your requirement
err => console.log(err),
() => console.log(`Success: ${success}\nErrors: ${errors}`),
);
}
顺序请求
对顺序数据流使用 RxJS from
function and concatMap
运算符。尝试以下
import { forkJoin, of, from } from 'rxjs';
import { tap, catchError, concatMap } from 'rxjs/operators';
putDataSequential() {
let success = 0; // <-- trivial counters
let errors = 0;
from(this.urls).pipe( // <-- replate `this.urls` with your object array
concatMap(url => {
return this.http.put(url).pipe( // <-- replace `url` with your own PUT request
tap(_ => success++), // <-- count successful responses here
catchError(err => {
errors++; // <-- count errors here
return of(err); // <-- remember to return an observable from `catchError`
})
)
})
).subscribe(
null, // <-- you could change response callback to your requirement
err => console.log(err),
() => console.log(`Success: ${success}\nErrors: ${errors}`),
);
}
无论错误或响应如何,这两种方法都将 运行 直到数组中的所有对象都完成。但是,如果您希望在出现错误时中断序列,请替换 catchError
运算符中的 return of(err);
语句以抛出 error
或 complete
通知。例如你可以使用 RxJS EMPTY
常量:return EMPTY;
.
我以普通计数器为例。您可以改为使用对象(例如)来记录 response/errors 的数量和 HTTP 请求的相应输入。
工作示例:Stackblitz
如您所见,每个项目都将使用 concateMap 进行处理,并且在发出 HTTP
请求后,每个项目 result
数组都会更新。
有多种方法,你可以达到这个结果。这是此处显示的方法之一。
items =[
{id: "3e81731f-e3b4-405d-a5ca-bef52c1b036a", name :'united', result:[]},
{id: "4707bff2-8265-456f-a4d4-ca1134d85620", name: 'ind', result:[]},
{id: "d29a3340-04b6-431b-8671-a0f0d25a9b51", name:'ru', result:[]},
{id: "xxx-xxxx-xxxx-xxxxx", name:'', result:[]}
]
from(this.items)
.pipe(
concatMap(item => this.ob2(item.name).pipe(
catchError(err=>of(err)),
tap(result =>{
if(result.length){
item.result = result;
}else{
// error scenario can be handled here
}
console.log('Updated each item', item)
})
))
).subscribe();
}