4

I am trying to get hang of async/await with below implementation but it is not working as expected

    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 will resolve promise after n milliseconds, and await should sleep till that time..

but below test of mine is failing

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

with message

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

my understanding was: sleep will await till the promise from _sleep is resolved (which as per setTimeout will resolve after 500ms)

EDIT

the test framework in mocha

harishr
  • 17,807
  • 9
  • 78
  • 125
  • 6
    You never await the result in your test when you call `Utilities.sleep(500);` See https://github.com/jasmine/jasmine/issues/923 – Igor May 25 '17 at 13:29
  • `async` function is just a function that returns a promise. Calling it won't magically turn asynchronous code into synchronous. It's not clear what the question is. Is it about async function or tests? If the former, then test example is irrelevant. If the latter, then the question is lacking, it doesn't even mention which testing framework you use. So is it about testing or about async/await? – Estus Flask May 25 '17 at 13:32
  • @estus I know its not magic, and hence trying to learn something which I dont understand. the question is about implemention `sleep` in javascript – harishr May 26 '17 at 03:25
  • It might be worth noting that your `sleep()` method adds no value over `_sleep()`. They both return a promise that resolves after `ms` milliseconds and can be used interchangeably. – user3432422 May 26 '17 at 13:10
  • @user3432422 great point, thanks a lot for that info – harishr May 26 '17 at 15:32

2 Answers2

7

You have not waited for your sleep() call (as described by the user @igor in the comments of your question):

Simplified version:

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);
})
M.K
  • 1,464
  • 2
  • 24
  • 46
unional
  • 14,651
  • 5
  • 32
  • 56
2

Only await awaits, and at the call-site. await is also only valid inside async functions. Usage:

await promise;

Think of an async function as just a better way of writing a function that returns a promise. It's just syntactic sugar.

It's not possible to hide asynchronous semantics nested inside synchronous function calls, without changing the semantics of all the functions calling it, making them all async. Consider whether things return in this run of the event loop or later.

If you wonder why async semantics isn't the default, read why co-routines won't work on the web.

jib
  • 40,579
  • 17
  • 100
  • 158