我有2个实体:收款人和交易。我有payeeCreateEpic
可以对started
进行过滤,以发出finished
/ failed
的规则链。 transactionCreateEpic
也是一样。
为简单起见,假设收款人只有UUID和名称。但是,交易可能具有以下三种可能性之一:未附加到任何收款人(有效载荷为payee: null
),未连接到现有收款人(在用户界面上,用户从下拉列表中选择了其中一个的所有收款人,下拉菜单中有{ {1}}或附加到非现有收款人(在用户界面上,用户可以选择创建收款人,该收款人不会保存到后端,但是如果保存了整个交易,则应保存在我发送了payee: payee-uuid
的有效负载。
现在,如果创建交易是在没有收款人或现有收款人的情况下提交的,那么我只需转到payee: payee-name
并等待其解决,以便发出POST /transactions
或finished
的操作{1}}。
但是,如果failed
的计算结果为true,则在transactionCreateEpic
的史诗内部,我想用收款人姓名启动!isUuid(txPayload.payee)
,然后等待transactionCreateEpic
=>然后创建从后端使用收款人ID进行交易,或payeeCreateEpic
=>中止交易(并向用户显示错误)。
我不确定该怎么做,因为在交易史诗中,我已经在finished
动作的过滤器中,并且不确定如何订阅failed
发出的另一个动作
某些代码:
TRANSACTION_CREATE_STARTED
看看payeeCreateEpic
,这是我很难真正启动createPayeeEpic +等待失败成功的地方。
答案 0 :(得分:0)
您的问题看起来像线程同步之一。 使用线程同步模式之一。 例如。 https://en.wikipedia.org/wiki/Monitor_(synchronization)
答案 1 :(得分:0)
解决方案是将事务的实际创建提取为某种工厂方法:
const transactionCreateStreamFactory = (action: MoneyPinAction<CreateActionParams>) =>
from(MoneyPinApiClient.getInstance().transaction.create(CreateRequestAdapter(action.payload))).pipe(
concatMap((response) => CreateAction.success({
params: action.payload,
result: CreateResultAdapter(response.data)
})),
catchError((err) => of(
<any>CreateAction.failure({params: action.payload, error: err}),
<any>MoneyPinApiErrorAction(err)
))
);
然后创建事务史诗实际上看起来像这样:
const createTransactionEpic = (actions$: Observable<Action>) =>
actions$.pipe(
filter(CreateAction.start.match),
mergeMap((action) => {
const {payee, payload} = action.payload;
if (payee && payload.payee_id) {
return merge(
actions$.pipe(
filter(PayeeCreateAction.success.match),
filter((payeeResponse) => payeeResponse.payload.result.payee.id === payload.payee_id),
take(1),
mergeMap(() => transactionCreateStreamFactory(action)),
),
actions$.pipe(
filter(PayeeCreateAction.failure.match),
filter((payeeResponse) => payeeResponse.payload.params.payload.id === payload.payee_id),
take(1),
map(() => CreateAction.failure({
params: action.payload,
error: new Error("failed to create payee")
}))
)
).pipe(
startWith(PayeeCreateAction.start({
notebook_id: action.payload.notebook_id,
payload: {id: payload.payee_id, name: payee}
}))
);
} else {
return transactionCreateStreamFactory(action);
}
})
);
因此,如果在创建过程中指定了具有ID的收款人,则我将启动另一个管道,该管道将监听payee.success
或payee.failure
动作,过滤相关动作(以防这种类型的多个动作可能是在并发创建过程中发生的),仅监听一次(take(1)
),然后将其合并到实际的create transaction史诗中,整个流程以收款人史诗处理的payee.start
操作开头(转而发出收款人操作的成功/失败)。