仅在另一部史诗完结后才如何散发史诗?

时间:2019-01-04 15:36:07

标签: javascript redux rxjs redux-observable

我有2个实体:收款人和交易。我有payeeCreateEpic可以对started进行过滤,以发出finished / failed的规则链。 transactionCreateEpic也是一样。

为简单起见,假设收款人只有UUID和名称。但是,交易可能具有以下三种可能性之一:未附加到任何收款人(有效载荷为payee: null),未连接到现有收款人(在用户界面上,用户从下拉列表中选择了其中一个的所有收款人,下拉菜单中有{ {1}}或附加到现有收款人(在用户界面上,用户可以选择创建收款人,该收款人不会保存到后端,但是如果保存了整个交易,则应保存在我发送了payee: payee-uuid的有效负载。

现在,如果创建交易是在没有收款人或现有收款人的情况下提交的,那么我只需转到payee: payee-name并等待其解决,以便发出POST /transactionsfinished的操作{1}}。

但是,如果failed的计算结果为true,则在transactionCreateEpic的史诗内部,我想用收款人姓名启动!isUuid(txPayload.payee),然后等待transactionCreateEpic =>然后创建从后端使用收款人ID进行交易,或payeeCreateEpic =>中止交易(并向用户显示错误)。

我不确定该怎么做,因为在交易史诗中,我已经在finished动作的过滤器中,并且不确定如何订阅failed发出的另一个动作

某些代码:

TRANSACTION_CREATE_STARTED

看看payeeCreateEpic,这是我很难真正启动createPayeeEpic +等待失败成功的地方。

2 个答案:

答案 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.successpayee.failure动作,过滤相关动作(以防这种类型的多个动作可能是在并发创建过程中发生的),仅监听一次(take(1)),然后将其合并到实际的create transaction史诗中,整个流程以收款人史诗处理的payee.start操作开头(转而发出收款人操作的成功/失败)。