Tidur skrip

136

Saya sedang mengembangkan sebuah situs web di Angular 2 menggunakan Typescript dan saya bertanya-tanya apakah ada cara untuk mengimplementasikan thread.sleep(ms)fungsionalitas.

Kasus penggunaan saya adalah untuk mengarahkan ulang pengguna setelah mengirimkan formulir setelah beberapa detik yang sangat mudah dalam html atau javascript, tetapi saya tidak yakin bagaimana melakukannya dalam skrip.

Terimakasih banyak,

kha
sumber
8
Naskah adalah superset dari JavaScript. Jadi, tulis dalam JavaScript, dan begitulah: Anda memiliki solusi TypeScript.
JB Nizet

Jawaban:

203

Anda harus menunggu TypeScript 2.0 dengan async/ awaituntuk dukungan ES5 karena sekarang hanya didukung untuk kompilasi TS ke ES6.

Anda dapat membuat fungsi penundaan dengan async:

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

Dan sebut saja

await delay(300);

Harap dicatat, bahwa Anda awaithanya dapat menggunakan asyncfungsi di dalam .

Jika Anda tidak bisa ( katakanlah Anda sedang membangun aplikasi nodejs ), cukup tempatkan kode Anda dalam asyncfungsi anonim . Berikut ini sebuah contoh:

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

        await delay(1000);

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

Contoh Aplikasi TS: https://github.com/v-andrew/ts-template

Di OLD JS Anda harus menggunakan

setTimeout(YourFunctionName, Milliseconds);

atau

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

Namun dengan setiap browser utama yang mendukung async/ awaititu usang.

Pembaruan: TypeScript 2.1 ada di sini bersama async/await.

Hanya saja, jangan lupa bahwa Anda perlu Promiseimplementasi ketika Anda mengkompilasi ke ES5, di mana Janji tidak tersedia secara asli.

v-andrew
sumber
1
Pembaruan : async / menunggu dan dukungan generator untuk ES5 / ES3 dipindahkan ke TypeScript 2.1
v-andrew
8
acara tanpa menunggu, Anda dapat melakukan penundaan (20000). kemudian (() => {
ZZZ
1
untuk beberapa alasan ini tidak berhasil untuk saya await new Promise(resolve => setTimeout(resolve, 1000)).then(()=>console.log("fired"));tetapi ini berhasilawait new Promise(resolve => setTimeout(()=>resolve(), 1000)).then(()=>console.log("fired"));
fjch1997
@ fjch1997, bungkus dengan asyncfungsi. Saya menambahkan contoh
v-andrew
2
Deklarasi fungsi 'tunda' tidak perlu kata kunci async, karena sudah mengembalikan janji.
SlavaSt
91

Ini bekerja: (terima kasih atas komentarnya)

setTimeout(() => 
{
    this.router.navigate(['/']);
},
5000);
kha
sumber
1
Saya kira yang ini harus menjadi jawaban yang diterima sekarang demi kesederhanaan.
displayname
1
@StefanFalk Hai Stefan. Saya menerima jawaban yang lain karena itu termasuk jawaban ini dan juga memiliki cara lain yang lebih "mengetik naskah" untuk melakukan penundaan yang mungkin menarik bagi orang lain. Saya pribadi menggunakan ini di seluruh kode saya karena saya tidak melihat manfaat apa pun dalam menggunakan async / menunggu untuk tugas khusus ini tapi saya bukan purist TS dan saya pergi dengan apapun yang lebih mudah / lebih mudah dibaca, jadi saya setuju dengan Anda pada prinsipnya :).
kha
31

Untuk beberapa alasan jawaban yang diterima di atas tidak berfungsi di Versi baru Angular (V6).

untuk itu gunakan ini ..

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

di atas bekerja untuk saya.

Pemakaian:

this.delay(3000);

ATAU cara yang lebih akurat

this.delay(3000).then(any=>{
     //your task after delay.
});
MarmiK
sumber
Cukup ganti '1000' Anda dengan panggilan parameter ms dan itu akan sempurna.
greenskin
15

Dengan RxJS:

import { timer } from 'rxjs';

// ...

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

x adalah 0.

Jika Anda memberikan argumen kedua perioduntuk timer, nomor baru akan dipancarkan setiap periodmilidetik (x = 0 maka x = 1, x = 2, ...).

Lihat dokumen resmi untuk lebih jelasnya.

Qortex
sumber
3
Terima kasih atas perspektif ini, datang ke sini untuk menemukan "cara yang dapat diamati"
user230910
0

Jika Anda menggunakan angular5 dan di atas, harap sertakan metode di bawah ini dalam file ts Anda.

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

lalu panggil metode delay () ini di mana pun Anda inginkan.

misalnya:

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

Ini akan menghilangkan pesan menggeram setelah 3 detik.

Perasaan
sumber
0
import { timer } from 'rxjs';

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

ini bekerja lebih baik untuk saya

FabioLux
sumber
Properti 'take' tidak ada pada tipe 'Observable <number>'.
Anton Duzenko
impor {take} dari 'rxjs / operator';
FabioLux
-2

Atau daripada mendeklarasikan suatu fungsi, cukup:

setTimeout(() => {
    console.log('hello');
}, 1000);
Gebus
sumber
Kenapa bukan fungsi?
Naveen Kumar