Sono datilografado

136

Estou desenvolvendo um site no Angular 2 usando o Typecript e fiquei imaginando se havia uma maneira de implementar a thread.sleep(ms)funcionalidade.

Meu caso de uso é redirecionar os usuários após o envio de um formulário após alguns segundos, o que é muito fácil em html ou javascript, mas não sei como fazê-lo no TypeScript.

Muito Obrigado,

kha
fonte
8
Texto datilografado é um superconjunto de JavaScript. Então, escreva-o em JavaScript e pronto: você tem uma solução TypeScript.
JB Nizet

Respostas:

203

Você precisa aguardar o suporte ao TypeScript 2.0 com async/ awaitpara ES5, pois agora ele é compatível apenas com a compilação de TS para ES6.

Você seria capaz de criar uma função de atraso com async:

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

E chame

await delay(300);

Observe que você pode usar awaitapenas a asyncfunção interna .

Se você não puder ( digamos que esteja criando o aplicativo nodejs ), basta colocar seu código na asyncfunção anônima . Aqui está um exemplo:

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

        await delay(1000);

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

Exemplo de aplicativo TS: https://github.com/v-andrew/ts-template

No OLD JS você tem que usar

setTimeout(YourFunctionName, Milliseconds);

ou

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

No entanto, com todos os principais navegadores de suporte async/ awaité obsoleto.

Atualização: O TypeScript 2.1 está aqui com async/await.

Apenas não esqueça que você precisa de Promiseimplementação ao compilar no ES5, onde o Promise não está disponível nativamente.

v-andrew
fonte
1
Atualização : async / await e geradores suporte para ES5 / ES3 foi transferido para typescript 2.1
v-andrew
8
sem aguardar, você pode atrasar (20000) .then (() => {
ZZZ
1
por algum motivo isso não funcionou para mim await new Promise(resolve => setTimeout(resolve, 1000)).then(()=>console.log("fired"));, mas isso funcionouawait new Promise(resolve => setTimeout(()=>resolve(), 1000)).then(()=>console.log("fired"));
fjch1997
@ fjch1997, envolva-o em asyncfunção. Eu adicionei exemplo
v-andrew
2
A declaração da função 'delay' não precisa da palavra-chave assíncrona, pois já retorna uma promessa.
SlavaSt
91

Isso funciona: (graças aos comentários)

setTimeout(() => 
{
    this.router.navigate(['/']);
},
5000);
kha
fonte
1
Acho que essa deve ser a resposta aceita até agora por uma questão de simplicidade.
displayname
1
@StefanFalk Oi Stefan. Aceitei a outra resposta porque ela incluía essa resposta e também tinha outras formas mais "tipográficas" de fazer o atraso que pode ser do interesse de outras pessoas. Pessoalmente, uso este em todo o meu código, pois não vejo nenhum benefício em usar async / waitit para esta tarefa específica, mas não sou um purista de TS e aceito o que for mais fácil / mais legível, por isso concordo com você em princípio :).
Kha #
31

Por algum motivo, a resposta aceita acima não funciona em Novas versões do Angular (V6).

para isso use isso ..

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

acima funcionou para mim.

Uso:

this.delay(3000);

OU maneira mais precisa

this.delay(3000).then(any=>{
     //your task after delay.
});
MarmiK
fonte
Basta substituir o seu '1000' pela chamada de parâmetro ms e seria perfeito.
Greenskin
15

Com RxJS:

import { timer } from 'rxjs';

// ...

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

x é 0.

Se você der um segundo argumento periodpara timer, um novo número será emitido a cada periodmilissegundo (x = 0 e x = 1, x = 2, ...).

Veja o documento oficial para mais detalhes.

Qortex
fonte
3
Obrigado por essa perspectiva, veio aqui para encontrar o "caminho observável"
user230910
0

Se você estiver usando angular5 e superior, inclua o método abaixo no seu arquivo ts.

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

em seguida, chame esse método delay () para onde desejar.

por exemplo:

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

Isso desaparecerá da mensagem após 3 segundos.

Entalhe
fonte
0
import { timer } from 'rxjs';

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

isso funciona melhor para mim

FabioLux
fonte
A propriedade 'take' não existe no tipo 'Observable <número>'.
Anton Duzenko 07/07
import {take} de 'rxjs / operadores';
FabioLux 8/07
-3

Ou, em vez de declarar uma função, simplesmente:

setTimeout(() => {
    console.log('hello');
}, 1000);
Gebus
fonte
Por que não uma função?
Naveen Kumar