Машинописный сон


138

Я разрабатываю веб-сайт на Angular 2 с использованием Typescript, и мне было интересно, есть ли способ реализовать thread.sleep(ms)функциональность.

Мой вариант использования - перенаправить пользователей после отправки формы через несколько секунд, что очень просто в html или javascript, но я не уверен, как это сделать в Typescript.

Большое спасибо,


8
Typescript - это надмножество JavaScript. Так что напишите его на JavaScript, и готово: у вас есть решение TypeScript.
JB Nizet

Ответы:


205

Вам нужно дождаться 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

В OLD JS вы должны использовать

setTimeout(YourFunctionName, Milliseconds);

или

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

Однако с каждым из основных браузеров поддержки async/ awaitона устарела.

Обновление: TypeScript 2.1 здесь с async/await.

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


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

8
событие без ожидания, вы можете сделать delay (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
Объявление функции 'delay' не требует ключевого слова async, поскольку оно уже возвращает обещание.
SlavaSt 05

94

Это работает: (спасибо за комментарии)

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

1
Думаю, для простоты этот ответ уже должен быть принятым.
displayname

1
@StefanFalk Привет, Стефан. Я принял другой ответ, потому что он включал этот ответ, а также имел другие, более "машинописные" способы выполнения задержки, которые могут быть интересны другим. Я лично использую его во всем своем коде, так как я не вижу никакой пользы в использовании async / await для этой конкретной задачи, но я не пурист TS, и я использую то, что проще / читабельнее, поэтому я согласен с вами в общем :).
kha

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, и это будет идеально.
greenskin

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"));
}

затем вызовите этот метод 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>.
Антон Дузенко,

импорт {взять} из 'rxjs / operator';
FabioLux

-1

Или вместо того, чтобы объявлять функцию, просто:

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

Почему не функция?
Naveen Kumar
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.