Why `async/await` doesn't work in my case?

十年热恋 提交于 2019-12-03 16:27:25
Ayush Gupta

await only suspends when the value passed to it is a Promise. In your case, setTimeout returns a Number so await doesn't wait for it.

The correct code will be as follows:

async function test() {
    console.log('1');
    await new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('2');
            resolve()
        }, 0);
    });
    console.log('3');
}

Because setTimeout doesn't return a promise. await x only waits if x is a promise; if x isn't a promise, it's (effectively) wrapped in one as though you had await Promise.resolve(x). That means the code following it will run asynchronously but as soon as possible.*

If you want a promise version of setTimeout, see this question's answers. But even with that, your test function wouldn't use a callback, instead you'd just await the promise-enabled timeout:

function later(delay) {
    return new Promise(function(resolve) {
        setTimeout(resolve, delay);
    });
}

async function test() {
  console.log("1");
  await later(10);
  console.log("2");
  console.log("3");
}

test().catch(e => console.error(e));
console.log("After the call (just to prove it does wait for the timeout after 1 and before 2");

* On browsers, that's guaranteed to be before a setTimeout(..., 0) scheduled during the same task, because promise callbacks scheduled during a task occur just after the end of that task, before the next task is picked up from the queue (even if the next task was scheduled before the promise callback). More on this ("macrotasks" and "microtasks") in this question's answers.

You can await to that functions that returns Promise. setTimeout does not returns Promise. So in this case await used before the setTimeout does not has a sense.

You can wrap your setTimeout into a Promise and call resolve at the setTimeout function.

(async function test() {
    console.log('1');
    await new Promise((resolve, reject) => { 
         setTimeout(() => {
            console.log('2');
            resolve(); // also can pass a parameter here to get it via await.
         },0);
    });
    console.log('3');
})();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!