Búsqueda de sitios web

angular - ¿Cómo puedo crear un observable con un retraso?


Pregunta

Para fines de prueba, estoy creando objetos Observable que reemplazan el observable que sería devuelto por una llamada http real con Http.

Mi observable se crea con el siguiente código:

fakeObservable = Observable.create(obs => {
  obs.next([1, 2, 3]);
  obs.complete();
});

La cuestión es que este observable emite inmediatamente. ¿Hay alguna manera de agregar un retraso personalizado a su emisión?

Pista

Intenté esto:

fakeObservable = Observable.create(obs => {
  setTimeout(() => {
    obs.next([1, 2, 3]);
    obs.complete();
  }, 100);
});

Pero no parece funcionar.

Respuesta #1

Usando las siguientes importaciones:

import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/delay';

Prueba esto:

let fakeResponse = [1,2,3];
let delayedObservable = Observable.of(fakeResponse).delay(5000);
delayedObservable.subscribe(data => console.log(data));

ACTUALIZACIÓN: RXJS 6

La solución anterior ya no funciona realmente en versiones más nuevas de RXJS (y de Angular, por ejemplo).

Entonces el escenario es que tengo un array de elementos para verificar con una API. La API solo acepta un solo elemento, y no quiero saturar la API enviando todas las solicitudes a la vez. Así que necesito una liberación programada de elementos en el flujo Observable con un pequeño retraso entre ellos.

Utiliza las siguientes importaciones:

import { from, of } from 'rxjs';
import { delay } from 'rxjs/internal/operators';
import { concatMap } from 'rxjs/internal/operators';

Luego use el siguiente código:

const myArray = [1,2,3,4];

from(myArray).pipe(
        concatMap( item => of(item).pipe ( delay( 1000 ) ))
    ).subscribe ( timedItem => {
        console.log(timedItem)
    });

Básicamente crea un nuevo Observable 'demorado' para cada elemento en tu arreglo. Probablemente haya muchas otras formas de hacerlo, pero esto funcionó bien para mí y cumple con el formato 'nuevo' de RXJS.

Respuesta #2

En RxJS 5+ puedes hacerlo así

import { Observable } from "rxjs/Observable";
import { of } from "rxjs/observable/of";
import { delay } from "rxjs/operators";

fakeObservable = of('dummy').pipe(delay(5000));

En RxJS 6+

import { of } from "rxjs";
import { delay } from "rxjs/operators";

fakeObservable = of('dummy').pipe(delay(5000));

Si quieres retrasar cada valor emitido intenta

from([1, 2, 3]).pipe(concatMap(item => of(item).pipe(delay(1000))));

Respuesta #3

Lo que quieres es un temporizador:

// RxJS v6+
import { timer } from 'rxjs';

//emit [1, 2, 3] after 1 second.
const source = timer(1000).map(([1, 2, 3]);
//output: [1, 2, 3]
const subscribe = source.subscribe(val => console.log(val));

Artículos relacionados