3 回答
TA贡献1785条经验 获得超8个赞
只需使用范围运算符,它接受两个参数;start & count( range(start: number, count: number): Observable
) 并返回一个 Observable,该 Observable 发出一系列数字,您可以根据需要对其进行转换。
考虑以下示例:
interface Body {
name: string
}
class Component {
constructor(
private alertify: Alertify,
private cvmService: CvmService
) { }
public addMany(count: number, base: string): void {
return range(1, count).pipe(
/**
* transform each emitted number into a @Body
*/
map(number => {
const body: Body = { name: `${base}${number}` };
return body;
}),
toArray(), // <-- collect emitted values
/**
* transform the array of @Body[] returned by @toArray() into an
* array of Observables and use @forkJoik operator to wait for all
* Observables to complete
*/
switchMap(array => forkJoin(array.map(body => this.addOne(body))))
).subscribe(() => console.log("done!"))
}
/**
* transform each body into an Observable
* without subscribing to it
* use @tap operator to listen for events that will be raised
* by future subscriptions
*/
public addOne(body: Body): Observable<void> {
return this.cvmService.createServer(body)
.pipe(
tap({
next: () => this.alertify.success('New item was successfully created'),
error: error => this.alertify.error('\n' + error)
})
)
}
}
TA贡献1853条经验 获得超6个赞
生成是你的朋友:
const baseName = this.createItemForm.get('name').value + '-';
generate(1, x => x <= this.count, x => ++x).pipe(
map(val => baseName + val),
).subscribe(bodyName => {
// do something with your worker-1 .... worker-count
});
generate将生成从 1 到您的输入计数的序列。
map只会将您的前缀(例如“worker”)与要生成的数字连接起来bodyName。
...然后就取决于你了。从代码中尚不清楚您的 body 对象是什么样子,您想要对每个请求执行什么操作以及最终执行什么操作。
TA贡献1844条经验 获得超8个赞
尝试这个。例如 :
forkJoin([res1, res2, res3, res4, res5])
.pipe(map(data => data.reduce((result,arr)=>[...result,...arr],[])))
.subscribe(data =>{
this.autoCompleteValues = data;
console.log(this.autoCompleteValues);
});
TA贡献1818条经验 获得超7个赞
mergeMap将值转换为订阅的可观察量
mergeMap(value => observable) 将为您订阅并发出映射的可观察值的值。看起来您所需要的只是 mergeMap(body => service(body)) ,然后您就可以开始比赛了。
以下是您使用 RxJS 所做的事情的非常直接的翻译。如果你的代码有效,那么(理论上,我无法测试它)这个或非常类似的东西应该可以工作。
我不确定body您的示例中定义的位置,因此我假设它是一个具有某些属性的对象,并且您要向其添加另一个属性 ( name)
addItems(){
range(1, this.count).pipe(
map(i => ({
...body,
name: `${this.createItemForm.get('name').value}-${i}`
})),
mergeMap(body => this.cvmService.createServer(body))
).subscribe({
next: resp => {
this.alertify.success('New item was successfully created');
this.close(true);
},
error: err => this.alertify.error('\n' + err),
complete: () => console.log(`${this.count} items where succesfully created`)
});
}
forkJoin将可观察数组转换为响应数组
可以做同样的事情forkJoin,因为看起来您的服务调用发出一次并完成。
在这里,您首先需要创建所需的服务调用的数组。我通过将数组映射[1,2,3,4,5]到主体对象[{name:worker-1},{name:worker-2},{name:worker-3},{name:worker-4},{name:worker-5}],然后将主体对象映射到服务调用来实现此目的[observable,observable,observable,observable,observable]。
所有这些都是在没有任何 RxJS 的情况下完成的,RxJS 部分是forkJoin([observable,observable,...]). 它订阅每个可观察对象并等待它们全部完成。
不同之处在于 forkJoin 将以数组形式发出最终结果。如果您仍然想要针对每个结果发出警报并调用 this.close(true),那么我们需要检测每个服务调用(数组中的源可观察对象)来执行此操作。
当您订阅时,next回调将被给予一个数组。实现如下所示:
addItems(){
forkJoin(
Array.from(
{length: this.count},
(_,i) => i+1
).map(i => ({
...body,
name: `${this.createItemForm.get('name').value}-${i}`
})).map(body =>
this.cvmService.createServer(body).pipe(
tap(_ => {
this.alertify.success('New item was successfully created');
this.close(true);
})
)
)
).subscribe({
next: resp => {
console.log(`${resp.length} items where succesfully created`);
},
error: err => this.alertify.error('\n' + err)
});
}
添加回答
举报