哪个 rxjs 运算符类似于 concatmap 但在触发下一个请求之前等待每个请求?
What rxjs operator is like concatmap but waits for each request before firing the next?
例如,假设我想拨打一些 api 电话。我正在处理的 api 很容易出现竞争条件,所以如果我同时进行 3 个 api 调用来更新服务器上的相同数据,它可能会丢失一些数据。
因此我想对我的请求进行排队,然后触发一个请求,等待响应返回,然后再触发下一个请求。
基本上我需要类似 concatMap 的东西,但 concatMap 的问题是它会同时触发所有请求。我需要 concatMap 在触发下一个请求之前等待。我正在使用 rxjs 5.
这是一个使用 angular2 的插件,您可以在其中单击按钮。当您单击 1 秒按钮时,将在 1 秒后创建 returns 的可观察对象。有 2 秒和 3 秒按钮。
https://plnkr.co/edit/6F4JrVueQX8PjPinZqIk?p=preview
@Component({
selector: 'my-app',
template: `
<div>
<h2>Wait:</h2>
<button (click)="start(1)">1 sec</button>
<button (click)="start(2)">2 sec</button>
<button (click)="start(3)">3 sec</button>
</div>
`,
})
export class App {
constructor() {
}
start(wait) {
const waitSecs = parseInt(wait) * 1000;
of('clicked').delay(waitSecs).subscribe(
val => console.log(wait)
)
// Expected behavior:
// I click 3 sec, 2 sec, and 1 sec right after another. Then
// the console log should output 3, 2, 1. Right now it's
// outputting 1, 2, 3.
}
}
我对这个应用程序的理想行为是在我依次单击 3 秒、2 秒和 1 秒之后。然后控制台应该输出 3, 2, 1。现在是
输出 1, 2, 3.
您应该 post 一些代码。 concatMap
应该适用于您的用例。如果您在订阅前观察到触发,则意味着您需要使用 defer
运算符在订阅时触发,但没有代码示例很难说更多。
过去问题的有用链接:
由于您只想执行请求,因此可以使用 mergeMap()
运算符并将 concurrency
设置为 1。请注意,这意味着待发送的项目将在内部排队您的 mergeMap 运算符可能会导致内存问题。
Rx.Observable.from([3,5,2,1])
.mergeMap(
i => {
return Rx.Observable.of(i)
.do(i => console.log(`starting request for ${i}`))
.delay(1000)
.do(null,null, () => console.log(`finished request for ${i}`));
},
null,
1 /* concurrency limited to 1 */
)
.subscribe(val => console.log(`received value: ${val}`));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.2/Rx.js"></script>
例如,假设我想拨打一些 api 电话。我正在处理的 api 很容易出现竞争条件,所以如果我同时进行 3 个 api 调用来更新服务器上的相同数据,它可能会丢失一些数据。
因此我想对我的请求进行排队,然后触发一个请求,等待响应返回,然后再触发下一个请求。
基本上我需要类似 concatMap 的东西,但 concatMap 的问题是它会同时触发所有请求。我需要 concatMap 在触发下一个请求之前等待。我正在使用 rxjs 5.
这是一个使用 angular2 的插件,您可以在其中单击按钮。当您单击 1 秒按钮时,将在 1 秒后创建 returns 的可观察对象。有 2 秒和 3 秒按钮。
https://plnkr.co/edit/6F4JrVueQX8PjPinZqIk?p=preview
@Component({
selector: 'my-app',
template: `
<div>
<h2>Wait:</h2>
<button (click)="start(1)">1 sec</button>
<button (click)="start(2)">2 sec</button>
<button (click)="start(3)">3 sec</button>
</div>
`,
})
export class App {
constructor() {
}
start(wait) {
const waitSecs = parseInt(wait) * 1000;
of('clicked').delay(waitSecs).subscribe(
val => console.log(wait)
)
// Expected behavior:
// I click 3 sec, 2 sec, and 1 sec right after another. Then
// the console log should output 3, 2, 1. Right now it's
// outputting 1, 2, 3.
}
}
我对这个应用程序的理想行为是在我依次单击 3 秒、2 秒和 1 秒之后。然后控制台应该输出 3, 2, 1。现在是 输出 1, 2, 3.
您应该 post 一些代码。 concatMap
应该适用于您的用例。如果您在订阅前观察到触发,则意味着您需要使用 defer
运算符在订阅时触发,但没有代码示例很难说更多。
过去问题的有用链接:
由于您只想执行请求,因此可以使用 mergeMap()
运算符并将 concurrency
设置为 1。请注意,这意味着待发送的项目将在内部排队您的 mergeMap 运算符可能会导致内存问题。
Rx.Observable.from([3,5,2,1])
.mergeMap(
i => {
return Rx.Observable.of(i)
.do(i => console.log(`starting request for ${i}`))
.delay(1000)
.do(null,null, () => console.log(`finished request for ${i}`));
},
null,
1 /* concurrency limited to 1 */
)
.subscribe(val => console.log(`received value: ${val}`));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.2/Rx.js"></script>