Reactjs 如何将动作观察链接到同步发射,然后发射最终值
我有一个方法,它将一个可观察对象作为参数,并返回另一个可观察对象(如果您在Redux observable上速度很快,那么它就具有这种类型的签名Reactjs 如何将动作观察链接到同步发射,然后发射最终值,reactjs,typescript,rxjs,observable,redux-observable,Reactjs,Typescript,Rxjs,Observable,Redux Observable,我有一个方法,它将一个可观察对象作为参数,并返回另一个可观察对象(如果您在Redux observable上速度很快,那么它就具有这种类型的签名函数(action$:observate 但下面是代码片段: import { from, of, Observable } from 'rxjs'; import { filter, delay, mapTo, mergeMap, concatMap, tap, switchMap } from 'rxjs/operators'; // GOAL /
函数(action$:observate
但下面是代码片段:
import { from, of, Observable } from 'rxjs';
import { filter, delay, mapTo, mergeMap, concatMap, tap, switchMap } from 'rxjs/operators';
// GOAL
// synchronously post each period, when that's finished perform a get request
// postPeriods should only console the final POST_AND_GET_SUCCESS string that all was successful
interface ActionModel {
type: string;
payload: any;
}
const postPeriods = (action$: Observable<ActionModel>) => action$.pipe(
filter(action => action.type === 'POST_AND_GET_REQUEST'),
mergeMap(action =>
from(action.payload).pipe(
concatMap(period => of(`${period} post success`).pipe(
delay(1000),
tap(() => console.log(`${period} post success`)),
// this is wrong - we only want this to emit once
switchMap(response => of('get success').pipe(map => of('POST_AND_GET_SUCCESS')))
))
),
)
);
const postRequestAction = from([{ type: 'POST_AND_GET_REQUEST', payload: ['period 1', 'period 2'] }]);
// this should be a single 'POST_AND_GET_SUCCESS'
postPeriods(postRequestAction).subscribe(val => console.log(val));
import{from,of,Observable}from'rxjs';
从“rxjs/operators”导入{filter、delay、mapTo、mergeMap、concatMap、tap、switchMap};
//目标
//同步发布每个时段,完成后执行get请求
//postPeriods应该只控制最后一个POST_和_GET_SUCCESS字符串,这两个字符串都是成功的
接口动作模型{
类型:字符串;
有效载荷:任何;
}
const postPeriods=(action$:Observable)=>action$.pipe(
过滤器(action=>action.type==='POST\u和\u GET\u请求'),
合并映射(操作=>
来自(动作.有效载荷).管道(
concatMap(period=>of(`${period}post success`)。管道(
延迟(1000),
轻触(()=>console.log(`${period}post success`),
//这是错误的-我们只希望它发射一次
switchMap(response=>of('get success')。pipe(map=>of('POST_和_get_success'))
))
),
)
);
const postRequestAction=from([{type:'POST_AND_GET_REQUEST',有效负载:['period 1','period 2']);
//这应该是一个“发布并获得成功”
postPeriods(postRequestAction).subscribe(val=>console.log(val));
我知道我使用的开关映射是错误的,但我不知道如何将从
可观察对象或合并映射
操作符链接起来,以获得我想要的结果。在后期
史诗中,我建议您通过返回单个可观察对象来结束操作,而不是返回m多重可观测的
首先,您可以定义一个数组(observebleList
),该数组将包含一个可观察的列表。然后,您可以从延迟的中推送带有可观察的数组。最后但并非最不重要的一点是,您移动开关映射()
逻辑,使其仅在返回observebleList
时执行
import { from, of, Observable } from 'rxjs';
import { filter, delay, mapTo, mergeMap, concatMap, tap, switchMap } from 'rxjs/operators';
// GOAL
// synchronously post each period, when that's finished perform a get request
// postPeriods should only console the final POST_AND_GET_SUCCESS string that all was successful
interface ActionModel {
type: string;
payload: any;
}
const postPeriods = (action$: Observable<ActionModel>) => action$.pipe(
filter(action => action.type === 'POST_AND_GET_REQUEST'),
mergeMap(action => {
// replace the generics with a suitable typing
const observableList: Observable<any>[] = [];
const delayed = from(action.payload).pipe(
concatMap(period => of(`${period} post success`)
.pipe(
delay(1000),
tap(() => console.log(`${period} post success`)),
)),
)
observableList.push(delayed);
return observableList;
}),
switchMap(response => of('get success').pipe(map => of('POST_AND_GET_SUCCESS')))
);
const postRequestAction = from([{ type: 'POST_AND_GET_REQUEST', payload: ['period 1', 'period 2'] }]);
// this should be a single 'POST_AND_GET_SUCCESS'
postPeriods(postRequestAction).subscribe(val => {
console.log('end:', val);
});
这将确保“获取成功”
操作仅在请求完成并返回可观察对象后执行一次
import { from, of, Observable } from 'rxjs';
import { filter, delay, mapTo, mergeMap, concatMap, tap, switchMap } from 'rxjs/operators';
// GOAL
// synchronously post each period, when that's finished perform a get request
// postPeriods should only console the final POST_AND_GET_SUCCESS string that all was successful
interface ActionModel {
type: string;
payload: any;
}
const postPeriods = (action$: Observable<ActionModel>) => action$.pipe(
filter(action => action.type === 'POST_AND_GET_REQUEST'),
mergeMap(action => {
// replace the generics with a suitable typing
const observableList: Observable<any>[] = [];
const delayed = from(action.payload).pipe(
concatMap(period => of(`${period} post success`)
.pipe(
delay(1000),
tap(() => console.log(`${period} post success`)),
)),
)
observableList.push(delayed);
return observableList;
}),
switchMap(response => of('get success').pipe(map => of('POST_AND_GET_SUCCESS')))
);
const postRequestAction = from([{ type: 'POST_AND_GET_REQUEST', payload: ['period 1', 'period 2'] }]);
// this should be a single 'POST_AND_GET_SUCCESS'
postPeriods(postRequestAction).subscribe(val => {
console.log('end:', val);
});
import{from,of,Observable}from'rxjs';
从“rxjs/operators”导入{filter、delay、mapTo、mergeMap、concatMap、tap、switchMap};
//目标
//同步发布每个时段,完成后执行get请求
//postPeriods应该只控制最后一个POST_和_GET_SUCCESS字符串,这两个字符串都是成功的
接口动作模型{
类型:字符串;
有效载荷:任何;
}
const postPeriods=(action$:Observable)=>action$.pipe(
过滤器(action=>action.type==='POST\u和\u GET\u请求'),
合并映射(操作=>{
//用合适的类型替换泛型
常量可观察列表:可观察[]=[];
const delayed=from(action.payload).pipe(
concatMap(period=>of(`${period}post success`)
.烟斗(
延迟(1000),
轻触(()=>console.log(`${period}post success`),
)),
)
可观察列表推送(延迟);
返回观察者;
}),
switchMap(response=>of('get success')。pipe(map=>of('POST_和_get_success'))
);
const postRequestAction=from([{type:'POST_AND_GET_REQUEST',有效负载:['period 1','period 2']);
//这应该是一个“发布并获得成功”
postPeriods(postRequestAction).subscribe(val=>{
log('end:',val);
});
在后期
epic中,我建议您通过返回一个可观察值来结束操作,而不是返回多个可观察值
首先,您可以定义一个数组(observebleList
),该数组将包含一个可观察的列表。然后,您可以从延迟的中推送带有可观察的数组。最后但并非最不重要的一点是,您移动开关映射()
逻辑,使其仅在返回observebleList
时执行
import { from, of, Observable } from 'rxjs';
import { filter, delay, mapTo, mergeMap, concatMap, tap, switchMap } from 'rxjs/operators';
// GOAL
// synchronously post each period, when that's finished perform a get request
// postPeriods should only console the final POST_AND_GET_SUCCESS string that all was successful
interface ActionModel {
type: string;
payload: any;
}
const postPeriods = (action$: Observable<ActionModel>) => action$.pipe(
filter(action => action.type === 'POST_AND_GET_REQUEST'),
mergeMap(action => {
// replace the generics with a suitable typing
const observableList: Observable<any>[] = [];
const delayed = from(action.payload).pipe(
concatMap(period => of(`${period} post success`)
.pipe(
delay(1000),
tap(() => console.log(`${period} post success`)),
)),
)
observableList.push(delayed);
return observableList;
}),
switchMap(response => of('get success').pipe(map => of('POST_AND_GET_SUCCESS')))
);
const postRequestAction = from([{ type: 'POST_AND_GET_REQUEST', payload: ['period 1', 'period 2'] }]);
// this should be a single 'POST_AND_GET_SUCCESS'
postPeriods(postRequestAction).subscribe(val => {
console.log('end:', val);
});
这将确保“获取成功”
操作仅在请求完成并返回可观察对象后执行一次
import { from, of, Observable } from 'rxjs';
import { filter, delay, mapTo, mergeMap, concatMap, tap, switchMap } from 'rxjs/operators';
// GOAL
// synchronously post each period, when that's finished perform a get request
// postPeriods should only console the final POST_AND_GET_SUCCESS string that all was successful
interface ActionModel {
type: string;
payload: any;
}
const postPeriods = (action$: Observable<ActionModel>) => action$.pipe(
filter(action => action.type === 'POST_AND_GET_REQUEST'),
mergeMap(action => {
// replace the generics with a suitable typing
const observableList: Observable<any>[] = [];
const delayed = from(action.payload).pipe(
concatMap(period => of(`${period} post success`)
.pipe(
delay(1000),
tap(() => console.log(`${period} post success`)),
)),
)
observableList.push(delayed);
return observableList;
}),
switchMap(response => of('get success').pipe(map => of('POST_AND_GET_SUCCESS')))
);
const postRequestAction = from([{ type: 'POST_AND_GET_REQUEST', payload: ['period 1', 'period 2'] }]);
// this should be a single 'POST_AND_GET_SUCCESS'
postPeriods(postRequestAction).subscribe(val => {
console.log('end:', val);
});
import{from,of,Observable}from'rxjs';
从“rxjs/operators”导入{filter、delay、mapTo、mergeMap、concatMap、tap、switchMap};
//目标
//同步发布每个时段,完成后执行get请求
//postPeriods应该只控制最后一个POST_和_GET_SUCCESS字符串,这两个字符串都是成功的
接口动作模型{
类型:字符串;
有效载荷:任何;
}
const postPeriods=(action$:Observable)=>action$.pipe(
过滤器(action=>action.type==='POST\u和\u GET\u请求'),
合并映射(操作=>{
//用合适的类型替换泛型
常量可观察列表:可观察[]=[];
const delayed=from(action.payload).pipe(
concatMap(period=>of(`${period}post success`)
.烟斗(
延迟(1000),
轻触(()=>console.log(`${period}post success`),
)),
)
可观察列表推送(延迟);
返回观察者;
}),
switchMap(response=>of('get success')。pipe(map=>of('POST_和_get_success'))
);
const postRequestAction=from([{type:'POST_AND_GET_REQUEST',有效负载:['period 1','period 2']);
//这应该是一个“发布并获得成功”
postPeriods(postRequestAction).subscribe(val=>{
log('end:',val);
});
如果GET请求不需要以前post请求响应中的任何数据,您可以使用concat
在末尾添加GET操作
...
mergeMap(action =>
concat(
from(action.payload).pipe(
concatMap(period => of(`${period} post success`).pipe(
delay(1000),
tap(() => console.log(`${period} post success`)),
))
),
of('get success').pipe(map => of('POST_AND_GET_SUCCESS'))
)
)
...
如果GET请求不需要以前post请求响应中的任何数据,则可以使用concat
在末尾添加GET操作
...
mergeMap(action =>
concat(
from(action.payload).pipe(
concatMap(period => of(`${period} post success`).pipe(
delay(1000),
tap(() => console.log(`${period} post success`)),
))
),
of('get success').pipe(map => of('POST_AND_GET_SUCCESS'))
)
)
...
嗯……你是说switchMap语句中的操作只有在有效负载中的两项都完成后才能执行?@wentjun是的,没错。嗯……你是说switchMap语句中的操作