如何创建NGRX效果(如果有的话)每5秒从状态中获取一条记录?

时间:2020-04-02 12:29:30

标签: rxjs ngrx ngrx-store ngrx-effects ngrx-entity

我想使用NGRX创建消息队列,添加到队列的每条消息应显示5秒钟,然后从状态中删除,

  • 在队列中的最后一条消息超时后,应将空值分配给currentMessageId
  • 如果currentMessageId == null ,应立即从队列中提取
  • 消息

这是我的状态:

import { EntityState } from '@ngrx/entity';

export interface UiMessage {
  id: string;
  severity: 'info' | 'warn' | 'error' | 'success';
  summary?: string;
  detail: string;
}
export interface MessagesState extends EntityState<UiMessage>{
   currentMessageId: string;
}

我已经尝试过此代码,如果商店中总是有一条消息,它会很好地工作:

  takeMessageInterval$ = createEffect(() => {
    return timer(0, 5000).pipe(
      map(() => {
        return UiActions.takeNextMessage()
      })
    )
  });

但是考虑这种情况:

  • 效果计时器从第二秒0开始,而存储中没有消息
  • 已添加一条消息以在第二秒存储,然后该消息必须等待4秒钟才能打勾,然后在视图上显示
    • 我希望它尽快显示并在5秒钟后删除

这也是化简函数:

export const messagesReducer = createReducer<MessagesState>(
  initialState,
  on(UiActions.addStateMessage, (current, action) => {
    return messagesAdapter.addOne(action.message, current);
  }),
  on(UiActions.removeStateMessage, (current, action) => {
    return messagesAdapter.removeOne(action.id, current);
  }),
  on(UiActions.takeNextMessage, (current, action) => {
    // remove current message
    if (current.currentMessageId) {
      current = messagesAdapter.removeOne(current.currentMessageId, current);
    }

    // take next message id
    const nextId = current.ids[0] as string;
    current.currentMessageId = nextId;

    return current;
  }),
);

1 个答案:

答案 0 :(得分:0)

这里可能是一种方法,假设一次只能显示一条消息:

takeMessageInterval$ = createEffect(
  () => this.actions$.pipe(
    // Intercept when a message has been added
    ofType(UiActions.addStateMessage),
    concatMapTo( // Queue up the messages
      timer(5000).pipe( // Display it for 5 seconds
        endWith(UiActions.takeNextMessage()) // Display the next message and remove the current one
      )
    )
  )
);