315

I'm developing a website in Angular 2 using TypeScript and I was wondering if there was a way to implement thread.sleep(ms) functionality.

My use case is to redirect the users after submitting a form after a few seconds which is very easy in JavaScript but I'm not sure how to do it in TypeScript.

3
  • 12
    Typescript is a superset of JavaScript. So write it in JavaScript, and there you go: you have a TypeScript solution. Commented Jun 11, 2016 at 14:09
  • This has got simpler since this question was originally answered. See stackoverflow.com/a/39914235/328817 Commented Apr 21, 2021 at 9:00
  • check this stackoverflow.com/a/65487714/1104877 Commented Mar 28, 2023 at 9:23

9 Answers 9

580

You have to wait for TypeScript 2.0 with async/await for ES5 support as it now supported only for TS to ES6 compilation.

You would be able to create delay function with async:

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

And call it

await delay(1000);

BTW, you can await on Promise directly:

await new Promise(f => setTimeout(f, 1000));

Please note, that you can use await only inside async function.

If you can't (let's say you are building nodejs application), just place your code in the anonymous async function. Here is an example:

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

        await delay(1000);

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

Example TS Application: https://github.com/v-andrew/ts-template

In OLD JS you have to use

setTimeout(YourFunctionName, Milliseconds);

or

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

However with every major browser supporting async/await it is less useful.

Update: TypeScript 2.1 is here with async/await.

Just do not forget that you need Promise implementation when you compile to ES5, where Promise is not natively available.

PS

You have to export the function if you want to use it outside of the original file.

Sign up to request clarification or add additional context in comments.

10 Comments

Update: async/await and generators support for ES5/ES3 was moved to TypeScript 2.1
event without await, you can do delay(20000).then(()=>{
for some reason this didn't work for me await new Promise(resolve => setTimeout(resolve, 1000)).then(()=>console.log("fired")); but this worked await new Promise(resolve => setTimeout(()=>resolve(), 1000)).then(()=>console.log("fired"));
@fjch1997, wrap it in async function. I added example
The declaration of 'delay' function does not need async keyword, as it already returns a promise.
|
175

This works: (thanks to the comments)

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

6 Comments

I guess this one should be the accepted answer by now for the sake of simplicity.
@StefanFalk Hi Stefan. I accepted the other answer because it included this answer and also had other, more "typescripty" ways of doing the delay which may be of interest to others. I'm personally using this one throughout my code since I don't see any benefit in using async/await for this specific task but I'm not a TS purist and I go with whatever's easier/more readable, so I agree with you in principle :).
I bumped it. Clean and effective.
Although this deserves the upvote, this is not a real "sleep" functionality that we are used to. Our task gets executed after a certain time, but the thread itself never sleeps or waits. It just initiates another thread with a standing instruction to start after the given time.
Property 'router' does not exist on type 'ReportQueueDialog'.ts(2339)
|
36

For some reason the above accepted answer does not work in New versions of Angular (V6).

for that use this..

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

above worked for me.

Usage:

this.delay(3000);

OR more accurate way

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

1 Comment

Just replace your '1000' with ms parameter call and it would be perfect.
29

With RxJS:

import { timer } from 'rxjs';

// ...

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

x is 0.

If you give a second argument period to timer, a new number will be emitted each period milliseconds (x = 0 then x = 1, x = 2, ...).

See the official doc for more details.

1 Comment

Thanks for this perspective, came here to find the "observable way"
16

Or rather than to declare a function, simply:

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

2 Comments

Why not a function?
not doing anything
13

The correct way to do it from ES6 is

import { setTimeout } from 'timers/promises';

await setTimeout(5000);

Its the native node method now. https://nodejs.org/api/timers.html

1 Comment

timers/promises is a Node.js-only API. It cannot be used in browser code.
12
import { timer } from 'rxjs';
import { take } from 'rxjs/operators';

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

this works better for me

5 Comments

Property 'take' does not exist on type 'Observable<number>'.
import { take } from 'rxjs/operators';
@AntonDuzenko you have to put it in .pipe()
Cannot find module 'rxjs' or its corresponding type declarations.ts(2307)
A slightly newer take on this: await firstValueFrom(timer(1000)); Both firstValueFrom and timer are from rxjs. Or with an alias: const sleep = (ms: number) => firstValueFrom(timer(ms)); Usage: await sleep(1000); nowDoSomething();
1

If you are using angular5 and above, please include the below method in your ts file.

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

then call this delay() method wherever you want.

e.g:

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

This will disappear message growl after 3 seconds.

Comments

-1

You can also use RxJS:

import { of } from 'rxjs';
import { delay } from 'rxjs/operators';

async yourFunction() {
    yourCode;
    await this.delay(5000);
    yourCode;
}

delay(ms: number): Promise<any> {
    const dummyObservable = of();
    return dummyObservable.pipe(delay(ms)).toPromise();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.