异步/等待清晰度,带有睡眠示例

Posted

技术标签:

【中文标题】异步/等待清晰度,带有睡眠示例【英文标题】:async/await clarity, with sleep example 【发布时间】:2017-10-26 04:18:47 【问题描述】:

我正在尝试通过以下实现来解决 async/await 的问题,但它没有按预期工作

    public static async sleep(ms: number): Promise<void> 
        await Utilities._sleep(ms);
    

    private static _sleep(ms: number): Promise<> 
        return new Promise((resolve: Function) => setTimeout(resolve, ms));
    

_sleep 将在 n 毫秒后解析 promise,并且 await 应该 sleep 直到那个时间..

但我的以下测试失败了

it("should sleep for 500 ms", ()=> 
    const date1 = (new Date()).getTime();
    Utilities.sleep(500);
    const date2 = (new Date()).getTime();
    chai.expect(date2 - date1).to.least(500);
)

有消息

 sleep should sleep for 500 ms FAILED
    AssertionError: expected 2 to be at least 500

我的理解是:sleep 将等待来自_sleep 的承诺得到解决(根据 setTimeout 将在 500 毫秒后解决)

编辑

mocha中的测试框架

【问题讨论】:

当您致电Utilities.sleep(500); 时,您永远不会等待测试结果,请参阅github.com/jasmine/jasmine/issues/923 async 函数只是一个返回承诺的函数。调用它不会神奇地将异步代码转换为同步代码。目前尚不清楚问题是什么。是关于异步功能还是测试?如果是前者,那么测试示例是无关紧要的。如果是后者,那么问题就没有了,它甚至没有提到你使用的测试框架。那么是关于测试还是关于异步/等待? @estus 我知道这不是魔法,因此试图学习一些我不明白的东西。问题是关于在javascript中实现sleep 可能值得注意的是,您的sleep() 方法没有比_sleep() 增加任何价值。它们都返回一个在ms 毫秒后解析的承诺,并且可以互换使用。 @user3432422 很好,非常感谢您提供的信息 【参考方案1】:

您还没有等待您的sleep() 电话(如用户@igor 在您问题的cmets 中所述):

简化版:

async function sleep(ms: number) 
    await _sleep(ms);


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


console.time('start')
sleep(500).then(() => 
    console.timeEnd('start')
)

// If your test runner supports async:
it("should sleep for 500 ms", async () => 
    const date1 = (new Date()).getTime();
    await sleep(500);
    const date2 = (new Date()).getTime();
    chai.expect(date2 - date1).to.least(500);
)

【讨论】:

但我在sleep 中等待,这与test 中的等待有何不同 调用时还需要等待sleep(500) 添加了 await 也在测试中(等待 Utilities.sleep(500)),但这也不起作用。 也许你的测试运行器不支持异步? @unional 这就是在回答糟糕的问题时会发生的情况,它们会导致糟糕的答案。 OP 没有指定测试框架并表示它不重要,但它当然很重要。【参考方案2】:

只有await 等待,并且在呼叫站点await 也仅在 inside async 函数中有效。用法:

await promise;

async 函数视为编写返回承诺的函数的更好方法。这只是语法糖。

不可能隐藏嵌套在同步函数调用中的异步语义,而不改变所有调用它的函数的语义,使它们全部异步。考虑在事件循环的这次运行中或之后是否会返回。

如果您想知道为什么异步语义不是默认的,请阅读why co-routines won't work on the web。

【讨论】:

以上是关于异步/等待清晰度,带有睡眠示例的主要内容,如果未能解决你的问题,请参考以下文章

同步异步阻塞非阻塞可中断的睡眠不可中断的睡眠

在返回值之前等待委托执行

带有 ALAsset 缩略图的低清晰度

C#图片处理示例(裁剪,缩放,清晰度,水印)

promise详解

测试人一定要会的技能:selenium的三种等待方式解读,清晰明了