问题
I read about async/await
, but I've a critical question.
At first I explain an old example to show base of my question and then I ask my exact question.
Everybody know it:
console.log('1');
console.log('2');
console.log('3'); // Ex: 123
It is simple but in below case:
console.log('1');
setTimeout(()=>{
console.log('2');
},0);
console.log('3'); // Ex: 132
It is simple too, setTimeout
function is asynchronous
and JavaScript
jump from it and after resolve run its function, so we see 2
after 1
and 3
.
But, now I read async/await
and I wrote a function like this:
(async function test() {
console.log('1');
await setTimeout(()=>{
console.log('2');
},0);
console.log('3');
})(); // Ex: 132
The Export is 132
too, why? this is my question, why 3
run before 2
? I expect because of async/await
after 1
JavaScript wait for 2
and then wrote 3
. why 132
?
回答1:
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');
}
回答2:
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.
回答3:
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');
})();
来源:https://stackoverflow.com/questions/48617486/why-async-await-doesnt-work-in-my-case