Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

237
Vistas
Ejecute ngrx/effect fuera de la zona de Angular para evitar el tiempo de espera en Protractor

Acabo de empezar a escribir pruebas e2e para mi aplicación y tengo problemas de tiempo de espera con Protractor y ngrx/effects.

Tengo el siguiente efecto enviando una acción cada par de minutos:

 @Effect() setSessionTimer$ = this.actions$ .ofType(Auth.ActionTypes.SET_SECONDS_LEFT) .map(toPayload) .switchMap(secondsLeft => Observable.concat( Observable.timer((secondsLeft - 60) * 1000).map(_ => new Auth.SessionExpiringAction(60)), Observable.timer(60 * 1000).map(_ => new Auth.SessionExpiredAction()) ));

Intentar ejecutar una prueba de transportador hace que la prueba se agote con el siguiente error, ya que Angular no es estable.

Error: se agotó el tiempo de espera para que finalicen las tareas angulares asincrónicas después de 11 segundos. Esto puede deberse a que la página actual no es una aplicación de Angular. Consulte las preguntas frecuentes para obtener más detalles: https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular Mientras espera el elemento con el localizador - Localizador: Por (css selector, . barra de herramientas-título)

De acuerdo con este problema ( https://github.com/angular/protractor/issues/3349 ), necesito usar NgZone para ejecutar un intervalo Observable fuera de Angular. Probé diferentes combinaciones de this.ngZone.runOutsideAngular() pero nada funcionó y las pruebas siguen agotando el tiempo de espera.

Por ejemplo esto no funciona:

 @Effect() setSessionTimer$ = this.actions$ .ofType(Auth.ActionTypes.SET_SECONDS_LEFT) .map(toPayload) .switchMap(secondsLeft => this.ngZone.runOutsideAngular(() => Observable.concat( Observable.timer((secondsLeft - 60) * 1000).map(_ => new Auth.SessionExpiringAction(60)), Observable.timer(60 * 1000).map(_ => new Auth.SessionExpiredAction()) )));

No tengo idea de cómo ejecutar el efecto fuera de Angular. ¿Alguien ha probado con éxito e2e su aplicación ngrx?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

La solución es programar el temporizador observable para que se ejecute fuera de NgZone y luego volver a ingresar a la zona cuando ocurra algo interesante.

Primero, necesitará dos funciones de utilidad que envuelvan cualquier planificador y hagan que el efecto entre o salga de la zona:

 import { Subscription } from 'rxjs/Subscription'; import { Scheduler } from 'rxjs/Scheduler'; import { NgZone } from '@angular/core'; class LeaveZoneSchduler { constructor(private zone: NgZone, private scheduler: Scheduler) { } schedule(...args: any[]): Subscription { return this.zone.runOutsideAngular(() => this.scheduler.schedule.apply(this.scheduler, args) ); } } class EnterZoneScheduler { constructor(private zone: NgZone, private scheduler: Scheduler) { } schedule(...args: any[]): Subscription { return this.zone.run(() => this.scheduler.schedule.apply(this.scheduler, args) ); } } export function leaveZone(zone: NgZone, scheduler: Scheduler): Scheduler { return new LeaveZoneSchduler(zone, scheduler) as any; } export function enterZone(zone: NgZone, scheduler: Scheduler): Scheduler { return new EnterZoneScheduler(zone, scheduler) as any; }

Luego, al usar un programador (como asap o async ), puede hacer que una transmisión ingrese o salga de la zona:

 import { async } from 'rxjs/scheduler/async'; import { enterZone, leaveZone } from './util'; actions$.ofType('[Light] Turn On') .bufferTime(300, leaveZone(this.ngZone, async)) .filter(messages => messages.length > 0) .observeOn(enterZone(this.ngZone, async))

Tenga en cuenta que la mayoría de los operadores basados en el tiempo (como bufferTime , debounceTime , Observable.timer , etc.) ya aceptan un planificador alternativo. Solo necesita observeOn para volver a ingresar a la zona cuando sucede algo interesante.

over 4 years ago · Santiago Trujillo Denunciar

0

Para Angular 6 y RxJS 6 use el siguiente código:

 import { SchedulerLike, Subscription } from 'rxjs' import { NgZone } from '@angular/core' class LeaveZoneScheduler implements SchedulerLike { constructor(private zone: NgZone, private scheduler: SchedulerLike) { } schedule(...args: any[]): Subscription { return this.zone.runOutsideAngular(() => this.scheduler.schedule.apply(this.scheduler, args) ) } now (): number { return this.scheduler.now() } } class EnterZoneScheduler implements SchedulerLike { constructor(private zone: NgZone, private scheduler: SchedulerLike) { } schedule(...args: any[]): Subscription { return this.zone.run(() => this.scheduler.schedule.apply(this.scheduler, args) ) } now (): number { return this.scheduler.now() } } export function leaveZone(zone: NgZone, scheduler: SchedulerLike): SchedulerLike { return new LeaveZoneScheduler(zone, scheduler) } export function enterZone(zone: NgZone, scheduler: SchedulerLike): SchedulerLike { return new EnterZoneScheduler(zone, scheduler) }

El efecto debería verse así:

 import { asyncScheduler, queueScheduler } from 'rxjs' import { filter, observeOn, bufferTime } from 'rxjs/operators' import { enterZone, leaveZone } from './util'; actions$.ofType('[Light] Turn On') .pipe( bufferTime(300, leaveZone(this.ngZone, asyncScheduler)), filter(messages => messages.length > 0), observeOn(enterZone(this.ngZone, queueScheduler)), )
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda