Хорошо, я думаю, что я получил рабочее решение, использующее замыкание и немного модифицировавшее мое тестовое утверждение.
Во-первых, ожидаемая мраморная диаграмма должна выглядеть следующим образом
// input: a-------a-b-a------
// - expected: -----x-----x-y----x
// + expected: -----x----x-y----x
//
// Note above that the middle x and y emit at the same time as new
// `add*` actions on the source stream instead of one frame later
С этим небольшим изменением, которое по-прежнему согласуется с моим описанием в вопросе, я смог пройти тест со следующим:
import { of, timer, empty } from 'rxjs'
import { switchMap, mapTo, tap, merge } from 'rxjs/operators'
import { ofType } from '../operators'
import actionTypes from '../../actionTypes/notifications'
import { actionCreators } from '../..'
export default (delay = 3000) => actionStream => {
let immediateRemove
return actionStream.pipe(
ofType(actionTypes.ADD),
switchMap(action => {
let obs = empty()
if (immediateRemove) {
obs = of(immediateRemove)
}
const remove = actionCreators.notifications.remove(action.payload.id)
immediateRemove = remove
return obs.pipe(
merge(
timer(delay).pipe(
tap(() => {
immediateRemove = null
}),
mapTo(remove)
)
)
)
})
)
}
Я не знаю, является ли это лучшим или правильным способом решения, но я вполне уверен, что это способ.