Друкарський сон


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 до 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

У СТАРИЙ JS ви повинні використовувати

setTimeout(YourFunctionName, Milliseconds);

або

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

Однак з кожним головним браузером, який підтримує async/ awaitвін застарілий.

Оновлення: TypeScript 2.1 тут async/await.

Тільки не забувайте, що вам потрібна Promiseреалізація під час компіляції в ES5, де Promise доступний не в оригіналі.


1
Оновлення : підтримка async / wait і підтримка генераторів для ES5 / ES3 була перенесена на TypeScript 2.1
v-andrew

8
події, не чекаючи, ви можете затримати (20000) .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
Напевно, ця відповідь на сьогодні має бути прийнятою для простоти.
ім'я для відображення

1
@StefanFalk Привіт Стефане. Я прийняв іншу відповідь, тому що вона включала цю відповідь, а також мала інші, більш "шрифтові" способи затримки, які можуть зацікавити інших. Я особисто використовую цей код у всьому коді, оскільки я не бачу ніякої користі в застосуванні 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.
});

Просто замініть свій "1000" на виклик параметра ms, і це було б ідеально.
зелена шкіра

15

З RxJS:

import { timer } from 'rxjs';

// ...

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

x дорівнює 0.

Якщо ви даєте другий аргумент , periodщоб timerновий номер буде викидатися кожен periodмілісекунди (х = 0 , то х = 1, х = 2, ...).

Детальнішу інформацію див. У офіційному документі .


3
Дякуємо за цю перспективу, що прийшов сюди, щоб знайти "спостережуваний шлях"
user230910

0

Якщо ви використовуєте angular5 і вище, будь ласка, включіть у свій файл ts метод нижче.

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

тоді зателефонуйте до цього методу затримки () куди завгодно.

наприклад:

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 <число>'.
Антон Дузенко

import {take} з 'rxjs / operator';
FabioLux

-3

Або замість того, щоб оголосити функцію, просто:

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

Чому не функція?
Naveen Kumar
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.