Typoskript Schlaf


135

Ich entwickle eine Website in Angular 2 mit Typescript und habe mich gefragt, ob es eine Möglichkeit gibt, thread.sleep(ms)Funktionen zu implementieren .

Mein Anwendungsfall besteht darin, die Benutzer nach dem Absenden eines Formulars nach einigen Sekunden umzuleiten, was in HTML oder Javascript sehr einfach ist, aber ich bin mir nicht sicher, wie ich es in Typescript machen soll.

Danke vielmals,


8
Typoskript ist eine Obermenge von JavaScript. Schreiben Sie es also in JavaScript und los geht's: Sie haben eine TypeScript-Lösung.
JB Nizet

Antworten:


198

Sie müssen auf TypeScript 2.0 mit async/ awaitfür ES5-Unterstützung warten, da es jetzt nur für die Kompilierung von TS zu ES6 unterstützt wird.

Sie können eine Verzögerungsfunktion erstellen mit async:

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

Und nenn es

await delay(300);

Bitte beachten Sie, dass Sie awaitnur die Innenfunktion verwenden asynckönnen.

Wenn Sie dies nicht können ( sagen wir, Sie erstellen eine NodeJS-Anwendung ), platzieren Sie Ihren Code einfach in einer anonymen asyncFunktion. Hier ist ein Beispiel:

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

        await delay(1000);

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

Beispiel für eine TS-Anwendung: https://github.com/v-andrew/ts-template

In OLD JS müssen Sie verwenden

setTimeout(YourFunctionName, Milliseconds);

oder

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

Jedoch mit jedem großen Browser, der unterstützt async/ awaites ist veraltet.

Update: TypeScript 2.1 ist hier mit async/await.

Vergessen Sie jedoch nicht, dass Sie Promisebeim Kompilieren auf ES5 eine Implementierung benötigen, bei der Promise nicht nativ verfügbar ist.


1
Update : async / await und Generatoren Unterstützung für ES5 / ES3 wurde auf TypeScript 2.1
v-andrew

8
Ereignis ohne Wartezeit, können Sie Verzögerung (20000) .then (() => {
ZZZ

1
Aus irgendeinem Grund hat das bei mir nicht funktioniert, await new Promise(resolve => setTimeout(resolve, 1000)).then(()=>console.log("fired"));aber es hat funktioniertawait new Promise(resolve => setTimeout(()=>resolve(), 1000)).then(()=>console.log("fired"));
fjch1997

@ fjch1997, verpacke es in asyncFunktion. Ich fügte Beispiel hinzu
v-andrew

2
Die Deklaration der Funktion 'delay' benötigt kein asynchrones Schlüsselwort, da sie bereits ein Versprechen zurückgibt.
SlavaSt

91

Das funktioniert: (dank der Kommentare)

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

1
Ich denke, dies sollte der Einfachheit halber inzwischen die akzeptierte Antwort sein.
Anzeigename

1
@ StefanFalk Hallo Stefan. Ich habe die andere Antwort akzeptiert, weil sie diese Antwort enthielt und auch andere, "typischere" Möglichkeiten hatte, die Verzögerung zu beheben, die für andere von Interesse sein könnten. Ich persönlich verwende diesen Code in meinem gesamten Code, da ich keinen Vorteil darin sehe, async / await für diese spezielle Aufgabe zu verwenden, aber ich bin kein TS-Purist und gehe mit allem um, was einfacher / besser lesbar ist, also stimme ich Ihnen zu allgemein gesagt :).
Kha

30

Aus irgendeinem Grund funktioniert die oben akzeptierte Antwort in neuen Versionen von Angular (V6) nicht.

dafür benutze das ..

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

oben hat für mich gearbeitet.

Verwendung:

this.delay(3000);

ODER genauer Weg

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

Ersetzen Sie einfach Ihre '1000' durch den ms-Parameteraufruf und es wäre perfekt.
Grünhaut

14

Mit RxJS:

import { timer } from 'rxjs';

// ...

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

x ist 0.

Wenn Sie ein zweites Argument geben periodzu timer, wird eine neue Nummer jeweils abzugebenden periodMillisekunden (x = 0 , dann ist x = 1, x = 2, ...).

Weitere Informationen finden Sie im offiziellen Dokument .


3
Vielen Dank für diese Perspektive, kam hierher, um den "beobachtbaren Weg" zu finden
user230910

0

Wenn Sie angle5 und höher verwenden, fügen Sie bitte die folgende Methode in Ihre ts-Datei ein.

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

Rufen Sie dann diese delay () -Methode auf, wo immer Sie möchten.

z.B:

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

Das Knurren der Nachricht verschwindet nach 3 Sekunden.


0
import { timer } from 'rxjs';

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

Das funktioniert besser für mich


Die Eigenschaft 'take' ist für den Typ 'Observable <Nummer>' nicht vorhanden.
Anton Duzenko

{take} von 'rxjs / operator' importieren;
FabioLux

-2

Oder anstatt eine Funktion zu deklarieren, einfach:

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

Warum nicht eine Funktion?
Naveen Kumar
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.