นอนหลับพิมพ์


136

ฉันกำลังพัฒนาเว็บไซต์ใน Angular 2 โดยใช้ Typescript และฉันสงสัยว่ามีวิธีการใช้งานthread.sleep(ms)ฟังก์ชันหรือไม่

กรณีการใช้งานของฉันคือการเปลี่ยนเส้นทางผู้ใช้หลังจากส่งแบบฟอร์มหลังจากนั้นสองสามวินาทีซึ่งง่ายมากใน html หรือ javascript แต่ฉันไม่แน่ใจว่าจะทำอย่างไรใน typescript

ขอบคุณมาก,


8
typescript เป็นชุดของ JavaScript ดังนั้นเขียนมันใน JavaScript และไปที่นั่น: คุณมีโซลูชั่น TypeScript
JB Nizet

คำตอบ:


203

คุณต้องรอ TypeScript 2.0 พร้อมasync/ awaitสำหรับการสนับสนุน ES5 เนื่องจากตอนนี้รองรับเฉพาะการคอมไพล์ TS to ES6

คุณจะสามารถสร้างฟังก์ชั่นการหน่วงเวลาด้วยasync:

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

และเรียกมันว่า

await delay(300);

โปรดทราบว่าคุณสามารถใช้ฟังก์ชันawaitภายในเท่านั้นasync

หากคุณไม่สามารถ ( สมมติว่าคุณกำลังสร้างแอปพลิเคชัน nodejs ) เพียงแค่วางรหัสของคุณในasyncฟังก์ชั่นที่ไม่ระบุชื่อ นี่คือตัวอย่าง:

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

        await delay(1000);

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

ตัวอย่างแอปพลิเคชัน TS: https://github.com/v-andrew/ts-template

ใน OLD JS คุณต้องใช้

setTimeout(YourFunctionName, Milliseconds);

หรือ

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

อย่างไรก็ตามเบราว์เซอร์หลักทุกตัวรองรับasync/ awaitล้าสมัยแล้ว

UPDATE: typescript 2.1 async/awaitอยู่ที่นี่กับ

อย่าลืมว่าคุณต้องPromiseติดตั้งใช้งานเมื่อคุณคอมไพล์กับ ES5 โดยที่สัญญาไม่พร้อมใช้งาน


1
อัปเดต : การสนับสนุนasync / await และเครื่องกำเนิดไฟฟ้าสำหรับ ES5 / ES3ถูกย้ายไปเป็น TypeScript 2.1
v-andrew

8
เหตุการณ์โดยไม่ต้องรอคุณสามารถหน่วงเวลา (20,000) .then (() => {
ZZZ

1
ด้วยเหตุผลบางอย่างสิ่งนี้ไม่ได้ผลสำหรับฉันawait new Promise(resolve => setTimeout(resolve, 1000)).then(()=>console.log("fired"));แต่ใช้งานได้await new Promise(resolve => setTimeout(()=>resolve(), 1000)).then(()=>console.log("fired"));
fjch1997

@ fjch1997 ห่อไว้ในasyncฟังก์ชั่น ฉันเพิ่มตัวอย่าง
v-andrew

2
การประกาศฟังก์ชั่น 'ล่าช้า' ไม่จำเป็นต้องใช้คำหลัก async เนื่องจากส่งคืนสัญญาแล้ว
SlavaSt

91

งานนี้: (ขอบคุณความคิดเห็น)

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

1
ฉันเดาว่าอันนี้ควรเป็นคำตอบที่ได้รับการยอมรับในตอนนี้เพื่อความเรียบง่าย
displayname

1
@StefanFalk สวัสดีสเตฟาน ฉันยอมรับคำตอบอื่น ๆ เพราะมันรวมคำตอบนี้และยังมีวิธีอื่น ๆ อีกมากมาย "typescripty" ของการทำล่าช้าซึ่งอาจเป็นที่สนใจของผู้อื่น ฉันใช้สิ่งนี้ตลอดทั้งรหัสเพราะฉันไม่เห็นประโยชน์ใด ๆ ในการใช้ async / รองานนี้โดยเฉพาะ แต่ฉันไม่ใช่คนเจ้าระเบียบ TS และฉันไปกับสิ่งที่ง่ายขึ้น / อ่านง่ายขึ้นดังนั้นฉันจึงเห็นด้วยกับคุณ โดยหลักการแล้ว :)
คา

31

ด้วยเหตุผลบางอย่างคำตอบที่ได้รับการยอมรับข้างต้นจะไม่ทำงานใน Angular (V6) เวอร์ชั่นใหม่

สำหรับการใช้สิ่งนี้ ..

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

ข้างต้นทำงานให้ฉัน

การใช้งาน:

this.delay(3000);

หรือวิธีที่แม่นยำกว่า

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

เพียงแค่แทนที่ '1,000' ด้วยการเรียกพารามิเตอร์ ms และมันจะสมบูรณ์แบบ
greenskin

15

ด้วยRxJS:

import { timer } from 'rxjs';

// ...

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

x คือ 0

หากคุณให้อาร์กิวเมนต์ที่สองperiodกับtimerหมายเลขใหม่จะถูกปล่อยออกมาแต่ละperiodมิลลิวินาที (x = 0 แล้ว x = 1, x = 2, ... )

ดูเอกสารอย่างเป็นทางการสำหรับรายละเอียดเพิ่มเติม


3
ขอบคุณสำหรับมุมมองนี้มาที่นี่เพื่อค้นหา "วิธีสังเกต"
user230910

0

หากคุณกำลังใช้ angular5 ขึ้นไปโปรดรวมวิธีการด้านล่างในไฟล์ ts ของคุณ

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

จากนั้นเรียกใช้เมธอด delay () นี้ทุกที่ที่คุณต้องการ

เช่น:

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

นี่จะหายไปคำรามข้อความหลังจาก 3 วินาที


0
import { timer } from 'rxjs';

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

มันใช้งานได้ดีกว่าสำหรับฉัน


ไม่มีคุณสมบัติ 'take' ในประเภท 'Observable <number>'
Anton Duzenko

นำเข้า {take} จาก 'rxjs / โอเปอเรเตอร์';
FabioLux

-3

หรือแทนที่จะประกาศฟังก์ชั่นเพียงแค่:

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

ทำไมไม่ฟังก์ชั่น?
Naveen Kumar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.