Sonno dattiloscritto


136

Sto sviluppando un sito Web in Angular 2 usando Typescript e mi chiedevo se ci fosse un modo per implementare la thread.sleep(ms)funzionalità.

Il mio caso d'uso è reindirizzare gli utenti dopo aver inviato un modulo dopo pochi secondi, il che è molto semplice in HTML o JavaScript, ma non sono sicuro di come farlo in Typescript.

Grazie molto,


8
Typescript è un superset di JavaScript. Quindi scrivilo in JavaScript e il gioco è fatto: hai una soluzione TypeScript.
JB Nizet,

Risposte:


203

Devi aspettare TypeScript 2.0 con async/ awaitper il supporto ES5 poiché ora è supportato solo per la compilazione da TS a ES6.

Saresti in grado di creare una funzione di ritardo con async:

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

E chiamalo

await delay(300);

Si noti che è possibile utilizzare awaitsolo la asyncfunzione interna .

Se non è possibile ( supponiamo che si stia creando un'applicazione nodejs ), è sufficiente posizionare il codice in asyncfunzione anonima . Ecco un esempio:

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

        await delay(1000);

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

Esempio di applicazione TS: https://github.com/v-andrew/ts-template

In OLD JS devi usare

setTimeout(YourFunctionName, Milliseconds);

o

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

Tuttavia, con tutti i principali browser supportati async/ awaitè obsoleto.

Aggiornamento: TypeScript 2.1 è qui con async/await.

Non dimenticare che devi eseguire l' Promiseimplementazione quando esegui la compilazione su ES5, dove Promise non è disponibile in modo nativo.


1
Aggiornamento : il supporto asincrono / attende e generatori per ES5 / ES3 è stato spostato su TypeScript 2.1
v-andrew,

8
evento senza attendere, puoi fare un ritardo (20000) .then (() => {
ZZZ

1
per qualche motivo questo non ha funzionato per me await new Promise(resolve => setTimeout(resolve, 1000)).then(()=>console.log("fired"));ma ha funzionatoawait new Promise(resolve => setTimeout(()=>resolve(), 1000)).then(()=>console.log("fired"));
fjch1997,

@ fjch1997, avvolgilo in asyncfunzione. Ho aggiunto un esempio
v-andrew,

2
La dichiarazione della funzione "ritardo" non richiede una parola chiave asincrona poiché restituisce già una promessa.
SlavaSt

91

Questo funziona: (grazie ai commenti)

setTimeout(() => 
{
    this.router.navigate(['/']);
},
5000);

1
Immagino che questa dovrebbe essere la risposta accettata ormai per motivi di semplicità.
displayname

1
@StefanFalk Ciao Stefan. Ho accettato l'altra risposta perché includeva questa risposta e c'erano anche altri modi più "tipografici" di fare il ritardo che potrebbero essere di interesse per gli altri. Personalmente sto usando questo nel mio codice poiché non vedo alcun vantaggio nell'usare async / wait per questo compito specifico ma non sono un purista di TS e vado con tutto ciò che è più facile / più leggibile, quindi sono d'accordo con te in linea di principio :).
Kha

31

Per qualche motivo la risposta sopra accettata non funziona nelle nuove versioni di Angular (V6).

per questo usa questo ..

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

sopra ha funzionato per me.

Uso:

this.delay(3000);

O un modo più accurato

this.delay(3000).then(any=>{
     //your task after delay.
});

Sostituisci semplicemente il tuo "1000" con la chiamata al parametro ms e sarebbe perfetto.
pelle di vitello

15

Con RxJS:

import { timer } from 'rxjs';

// ...

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

x è 0.

Se si dà un secondo argomento perioda timer, verrà emesso un nuovo numero ciascunoperiod millisecondo (x = 0 quindi x = 1, x = 2, ...).

Vedi il documento ufficiale per maggiori dettagli.


3
Grazie per questa prospettiva, è venuto qui per trovare la "via osservabile"
user230910

0

Se si utilizza angular5 e versioni successive, includere il metodo seguente nel file ts.

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

quindi chiama questo metodo delay () dove vuoi.

per esempio:

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

Questo messaggio scompare ringherà dopo 3 secondi.


0
import { timer } from 'rxjs';

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

questo funziona meglio per me


La proprietà 'take' non esiste sul tipo 'Observable <number>'.
Anton Duzenko,

import {take} da 'rxjs / operatori';
FabioLux,

-2

O piuttosto che dichiarare una funzione, semplicemente:

setTimeout(() => {
    console.log('hello');
}, 1000);

Perché non una funzione?
Naveen Kumar,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.