如何在 TypeScript 中实现睡眠功能?

Posted

技术标签:

【中文标题】如何在 TypeScript 中实现睡眠功能?【英文标题】:How to implement sleep function in TypeScript? 【发布时间】:2016-10-12 09:23:19 【问题描述】:

我正在使用 TypeScript 在 Angular 2 中开发一个网站,我想知道是否有办法实现 thread.sleep(ms) 功能。

我的用例是在几秒钟后提交表单后重定向用户,这在 javascript 中非常简单,但我不确定如何在 TypeScript 中执行此操作。

【问题讨论】:

Typescript 是 JavaScript 的超集。所以用 JavaScript 编写它,然后就可以了:你有一个 TypeScript 解决方案。 自从最初回答了这个问题以来,这变得更简单了。见***.com/a/39914235/328817 【参考方案1】:

您必须等待带有 async/await 的 TypeScript 2.0 才能支持 ES5,因为它现在仅支持 TS 到 ES6 的编译。

您可以使用async 创建延迟函数:

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

然后叫它

await delay(1000);

顺便说一句,您可以直接在Promise 上等待:

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

请注意,您只能在 async 函数中使用 await

如果你不能(假设你正在构建 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 一起发布。

当你编译到 ES5 时,不要忘记你需要 Promise 实现,而 Promise 在本机不可用。

PS

如果你想在原始文件之外使用它,你必须export the function。

【讨论】:

更新对 ES5/ES3 的异步/等待和生成器支持已移至 TypeScript 2.1 没有等待的事件,可以做delay(20000).then(()=> 由于某种原因,这对我不起作用await new Promise(resolve => setTimeout(resolve, 1000)).then(()=>console.log("fired"));,但这对我有效await new Promise(resolve => setTimeout(()=>resolve(), 1000)).then(()=>console.log("fired")); @fjch1997,将其包装在async 函数中。我添加了示例 'delay'函数的声明不需要async关键字,因为它已经返回了一个promise。【参考方案2】:

这可行:(感谢 cmets)

setTimeout(() => 

    this.router.navigate(['/']);
,
5000);

【讨论】:

为了简单起见,我想这个应该是现在公认的答案。 @StefanFalk 你好 Stefan。我接受了另一个答案,因为它包含了这个答案,并且还有其他更“打字”的方式来做延迟,这可能会引起其他人的兴趣。我个人在我的代码中使用这个,因为我没有看到使用 async/await 来完成这个特定任务有任何好处,但我不是一个 TS 纯粹主义者,我会选择更容易/更易读的东西,所以我同意你的看法原则上:)。 我撞到了它。干净有效。【参考方案3】:

由于某种原因,上述接受的答案在新版本的 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.
);

【讨论】:

只需用 ms 参数调用替换你的 '1000' 就完美了。【参考方案4】:

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,...)。

有关详细信息,请参阅official doc。

【讨论】:

感谢这个观点,来到这里寻找“可观察的方式”【参考方案5】:

或者,与其声明一个函数,不如简单地:

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

【讨论】:

为什么不是函数?【参考方案6】:
import  timer  from 'rxjs';
import  take  from 'rxjs/operators';

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

这对我来说效果更好

【讨论】:

属性 'take' 不存在于类型 'Observable' 上。 import take from 'rxjs/operators'; @AntonDuzenko 你必须把它放在 .pipe() 中【参考方案7】:

如果您使用的是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 秒后消失消息咆哮。

【讨论】:

【参考方案8】:

你也可以使用 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();

【讨论】:

以上是关于如何在 TypeScript 中实现睡眠功能?的主要内容,如果未能解决你的问题,请参考以下文章

如何让一个类在 Typescript 中实现调用签名?

在 Typescript 中实现接口时如何定义私有属性?

如何在 TypeScript 中实现的接口中进行构造函数重载?

如何在 React TypeScript 中实现 e 和 props?

如何在TypeScript中实现redux中间件类

如何使用 jwt 在 typescript 中实现更改密码 API?