Sueño mecanografiado

136

Estoy desarrollando un sitio web en Angular 2 usando Typecript y me preguntaba si había una manera de implementar la thread.sleep(ms)funcionalidad.

Mi caso de uso es redirigir a los usuarios después de enviar un formulario después de unos segundos, lo cual es muy fácil en html o javascript, pero no estoy seguro de cómo hacerlo en Typecript.

Muchas gracias,

kha
fuente
8
El mecanografiado es un superconjunto de JavaScript. Escríbalo en JavaScript y listo: tiene una solución TypeScript.
JB Nizet

Respuestas:

203

Usted tiene que esperar a que mecanografiado 2.0 con async/ awaitpara el apoyo ES5 ya que ahora soporta sólo para TS a la compilación ES6.

Podrías crear una función de retraso con async:

function delay(ms: number) {
    return new Promise( resolve => setTimeout(resolve, ms) );
}

Y llámalo

await delay(300);

Tenga en cuenta que awaitsolo puede usar la asyncfunción interna .

Si no puede ( digamos que está creando una aplicación nodejs ), simplemente coloque su código en una asyncfunción anónima . Aquí hay un ejemplo:

    (async () => { 
        // Do something before delay
        console.log('before delay')

        await delay(1000);

        // Do something after
        console.log('after delay')
    })();

Aplicación de ejemplo de TS: https://github.com/v-andrew/ts-template

En OLD JS tienes que usar

setTimeout(YourFunctionName, Milliseconds);

o

setTimeout( () => { /*Your Code*/ }, Milliseconds );

Sin embargo, con todos los principales navegadores compatibles async/ awaites obsoleto.

Actualización: TypeScript 2.1 está aquí con async/await.

Simplemente no olvide que necesita Promiseimplementación cuando compila a ES5, donde Promise no está disponible de forma nativa.

v-andrew
fuente
1
Actualización : async / await y el soporte de generadores para ES5 / ES3 se movió a TypeScript 2.1
v-andrew
8
evento sin esperar, puede hacer un retraso (20000) .then (() => {
ZZZ
1
por alguna razón esto no funcionó para mí, await new Promise(resolve => setTimeout(resolve, 1000)).then(()=>console.log("fired"));pero funcionóawait new Promise(resolve => setTimeout(()=>resolve(), 1000)).then(()=>console.log("fired"));
fjch1997
@ fjch1997, envuélvelo en asyncfunción. Agregué un ejemplo
v-andrew el
2
La declaración de la función 'delay' no necesita una palabra clave asíncrona, ya que ya devuelve una promesa.
SlavaSt
91

Esto funciona: (gracias a los comentarios)

setTimeout(() => 
{
    this.router.navigate(['/']);
},
5000);
kha
fuente
1
Supongo que esta debería ser la respuesta aceptada por ahora en aras de la simplicidad.
mostrar
1
@StefanFalk Hola Stefan. Acepté la otra respuesta porque incluía esta respuesta y también tenía otras formas más "mecanografiadas" de retrasar que pueden ser de interés para otros. Personalmente estoy usando este en todo mi código ya que no veo ningún beneficio en usar async / wait para esta tarea específica, pero no soy un purista de TS y voy con lo que sea más fácil / más legible, así que estoy de acuerdo con usted en principio :).
Kha
31

Por alguna razón, la respuesta aceptada anteriormente no funciona en Nuevas versiones de Angular (V6).

para eso usa esto ..

async delay(ms: number) {
    await new Promise(resolve => setTimeout(()=>resolve(), ms)).then(()=>console.log("fired"));
}

arriba funcionó para mí.

Uso:

this.delay(3000);

O una forma más precisa

this.delay(3000).then(any=>{
     //your task after delay.
});
MarmiK
fuente
Simplemente reemplace su '1000' con la llamada de parámetro ms y sería perfecto.
greenskin
15

Con RxJS:

import { timer } from 'rxjs';

// ...

timer(your_delay_in_ms).subscribe(x => { your_action_code_here })

x es 0.

Si le da un segundo argumento perioda timer, se emitirá un nuevo número cada periodmilisegundos (x = 0 y luego x = 1, x = 2, ...).

Vea el documento oficial para más detalles.

Qortex
fuente
3
Gracias por esta perspectiva, vinieron aquí para encontrar el "camino observables"
user230910
0

Si está utilizando angular5 y superior, incluya el siguiente método en su archivo ts.

async delay(ms: number) {
    await new Promise(resolve => setTimeout(()=>resolve(), ms)).then(()=>console.log("fired"));
}

luego llame a este método delay () donde quiera.

p.ej:

validateInputValues() {
    if (null == this.id|| this.id== "") {
        this.messageService.add(
            {severity: 'error', summary: 'ID is Required.'});
        this.delay(3000).then(any => {
            this.messageService.clear();
        });
    }
}

Esto desaparecerá gruñendo el mensaje después de 3 segundos.

Punta
fuente
0
import { timer } from 'rxjs';

await timer(1000).take(1).toPromise();

esto funciona mejor para mi

FabioLux
fuente
La propiedad 'take' no existe en el tipo 'Observable <número>'.
Anton Duzenko
importar {tomar} de 'rxjs / operadores';
FabioLux
-2

O en lugar de declarar una función, simplemente:

setTimeout(() => {
    console.log('hello');
}, 1000);
Gebus
fuente
¿Por qué no una función?
Naveen Kumar el