2017-02-08 10 views
1

У меня есть два действия: a.load и b.load, а с их задней стороны зарегистрирован @effect, чтобы выполнить HTTP-вызов для c. Тем не менее, проблема возникает там, где при загрузке страницы отправляются как a, так и b, и в результате c запрашивается дважды. Причина, по которой мне нужно реагировать на оба действия, заключается в том, что на этой странице можно изменить a или b, и если да, мне нужно сделать запрос, чтобы получить новое значение для c.Несколько HTTP-запросов из-за одного эффекта и нескольких действий

Есть ли способ справиться с этим/избежать этого? Может быть, я мог бы рассмотреть возможность отмены любых предыдущих запросов внутри эффекта?

Спасибо.

ответ

1

Вы должны быть в состоянии решить эту проблему с помощью throttle operator - которая принимает функцию, которая возвращает наблюдаемую и, пока что наблюдаемые испускает любые значения, испускаемые источник не задушила/игнорируются.

Если вы передадите throttle сам эффект, любые действия, полученные во время обработки медленного запроса, будут проигнорированы. Например:

import 'rxjs/add/operator/throttle'; 

@Effect() 
someEffect = this.actions 
    .ofType(SOME_REQUEST) 
    .throttle(() => this.someEffect) 
    .switchMap((action) => someSlowRequest(action.payload) 
     .map((result) => ({ type: SOME_RESPONSE, payload: result })) 
     .catch((error) => Observable.of({ type: SOME_ERROR, payload: error })) 
    ); 

Если вы используете throttle таким образом с вашим HTTP на основе эффекта, он будет видеть какие-либо действия, которые вызывают эффект игнорируется, если есть запрос в ожидании HTTP. Поэтому, если это поведение, которое вы ищете, оно должно решить вашу проблему.

Что касается Вашего комментария, если вы хотите, последние из близкорасположенных действий, подлежащая обработке, вы могли бы рассмотреть вопрос об использовании auditTime operator - который будет ждать в течение заданного времени, а затем будет излучать последний полученное значение:

import 'rxjs/add/operator/auditTime'; 

@Effect() 
someEffect = this.actions 
    .ofType(SOME_REQUEST) 
    .auditTime(100) 
    .switchMap((action) => someSlowRequest(action.payload) 
     .map((result) => ({ type: SOME_RESPONSE, payload: result })) 
     .catch((error) => Observable.of({ type: SOME_ERROR, payload: error })) 
    ); 

В качестве альтернативы вы можете просто положиться на оператора switchMap - который отписывает при получении новых значений. Тем не менее, я понимаю, что действия ngrx отправляются синхронно, поэтому для каждого действия может быть сделан HTTP-запрос, и я не уверен, как реализация будет управлять их отменой - может быть, их ответы просто игнорируются.

+0

Спасибо за это предложение, однако я должен был отметить, что мне нужен последний звонок. Могу ли я отменить запрос, отказавшись от запроса? – maddockst

+0

Большое спасибо. Я думаю, мне нужно взглянуть на операторы rxjs. – maddockst

+1

Я обновил ответ. – cartant