Sommeil dactylographié

136

Je développe un site Web dans Angular 2 en utilisant Typescript et je me demandais s'il y avait un moyen d'implémenter des thread.sleep(ms)fonctionnalités.

Mon cas d'utilisation est de rediriger les utilisateurs après avoir soumis un formulaire après quelques secondes, ce qui est très facile en html ou javascript mais je ne sais pas comment le faire dans Typescript.

Merci beaucoup,

kha
la source
8
Typescript est un sur-ensemble de JavaScript. Alors écrivez-le en JavaScript, et voilà: vous avez une solution TypeScript.
JB Nizet du

Réponses:

203

Vous devez attendre TypeScript 2.0 avec async/ awaitpour la prise en charge d'ES5 car il n'est désormais pris en charge que pour la compilation TS vers ES6.

Vous seriez en mesure de créer une fonction de retard avec async:

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

Et appelle ça

await delay(300);

Veuillez noter que vous ne pouvez utiliser awaitque la asyncfonction interne .

Si vous ne pouvez pas ( disons que vous créez une application nodejs ), placez simplement votre code dans une asyncfonction anonyme . Voici un exemple:

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

        await delay(1000);

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

Exemple d'application TS: https://github.com/v-andrew/ts-template

Dans OLD JS, vous devez utiliser

setTimeout(YourFunctionName, Milliseconds);

ou

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

Cependant, avec tous les principaux navigateurs prenant en charge async/ awaitil est obsolète.

Mise à jour: TypeScript 2.1 est là avec async/await.

N'oubliez pas que vous avez besoin d'une Promiseimplémentation lorsque vous compilez vers ES5, où Promise n'est pas disponible nativement.

v-andrew
la source
1
Mise à jour : async / await et la prise en charge des générateurs pour ES5 / ES3 a été déplacée vers TypeScript 2.1
v-andrew
8
événement sans attendre, vous pouvez faire du retard (20000) .then (() => {
ZZZ
1
pour une raison quelconque, cela n'a pas fonctionné pour moi, await new Promise(resolve => setTimeout(resolve, 1000)).then(()=>console.log("fired"));mais cela a fonctionnéawait new Promise(resolve => setTimeout(()=>resolve(), 1000)).then(()=>console.log("fired"));
fjch1997
@ fjch1997, enveloppez-le dans la asyncfonction. J'ai ajouté un exemple
v-andrew
2
La déclaration de la fonction 'delay' n'a pas besoin de mot clé async, car elle renvoie déjà une promesse.
SlavaSt
92

Cela fonctionne: (grâce aux commentaires)

setTimeout(() => 
{
    this.router.navigate(['/']);
},
5000);
kha
la source
1
Je suppose que celle-ci devrait être la réponse acceptée maintenant par souci de simplicité.
displayname
1
@StefanFalk Salut Stefan. J'ai accepté l'autre réponse parce qu'elle incluait cette réponse et qu'il y avait aussi d'autres façons, plus «dactylographiées», de faire le retard qui pourraient intéresser d'autres. J'utilise personnellement celui-ci tout au long de mon code car je ne vois aucun avantage à utiliser async / await pour cette tâche spécifique, mais je ne suis pas un puriste TS et je vais avec ce qui est plus facile / plus lisible, donc je suis d'accord avec vous en principe :).
kha
31

Pour une raison quelconque, la réponse acceptée ci-dessus ne fonctionne pas dans les nouvelles versions d'Angular (V6).

pour cela, utilisez ceci ..

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

ci-dessus a fonctionné pour moi.

Usage:

this.delay(3000);

OU manière plus précise

this.delay(3000).then(any=>{
     //your task after delay.
});
MarmiK
la source
Remplacez simplement votre «1000» par un appel de paramètre ms et ce serait parfait.
greenskin
15

Avec RxJS:

import { timer } from 'rxjs';

// ...

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

x vaut 0.

Si vous donnez un deuxième argument periodà timer, un nouveau nombre sera émis toutes les periodmillisecondes (x = 0 puis x = 1, x = 2, ...).

Voir la documentation officielle pour plus de détails.

Qortex
la source
3
Merci pour cette perspective,
je suis
0

Si vous utilisez angular5 et supérieur, veuillez inclure la méthode ci-dessous dans votre fichier ts.

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

puis appelez cette méthode delay () où vous le souhaitez.

par exemple:

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

Ce message disparaîtra après 3 secondes.

Pointe
la source
0
import { timer } from 'rxjs';

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

cela fonctionne mieux pour moi

FabioLux
la source
La propriété 'take' n'existe pas sur le type 'Observable <number>'.
Anton Duzenko le
import {take} de 'rxjs / operators';
FabioLux
-2

Ou plutôt que de déclarer une fonction, simplement:

setTimeout(() => {
    console.log('hello');
}, 1000);
Gebus
la source
Pourquoi pas une fonction?
Naveen Kumar