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,

kha
quelle
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.

V-Andrew
quelle
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);
kha
quelle
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.
});
MarmiK
quelle
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 .

Qortex
quelle
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.

Jag
quelle
0
import { timer } from 'rxjs';

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

Das funktioniert besser für mich

FabioLux
quelle
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);
Gebus
quelle
Warum nicht eine Funktion?
Naveen Kumar