async function test(){
setTimeout(function(){return 1}, 100)
};
test().then(console.log); // Never displayed
If the setTimeout wrap is removed, it works:
async function test(){
return 1;
};
test().then(console.log); // Displayed
CodePudding user response:
First, you forgot the return statement in the test
function. Without a return statement, the function returns a Promise
which resolves to undefined
.
Second, setTimeout
does not return a promise. Instead, you have to create it explicitly.
It should be something like this.
async function test() {
return new Promise((resolve) => setTimeout(() => resolve(1), 100))
}
But your code is equivalent to the following because you do not use setTimeout
in any way.
async function test() {
return undefined
}
There are two options to create an async function. Historically the first one is that function accepts a callback. The second option is to return a promise from the function.
Many library functions accept a callback and call the callback when the async event happens. An example of such a function is the setTimeout
.
To use a function which accepts a callback with await
, you can wrap it in a new Promise.
For example, we have a library function libFunc(..., callback)
where callback
is a function which accepts some arguments.
You can create a new promise like this.
const result = await new Promise(
(resolve) => libFunc(/*some arguments*/,
(callbackArg) => resolve(callbackArg)))
You can check my post on the topic Async function from callback in JavaScript
CodePudding user response:
The below function does not return anything. Neither is it a promise, that it would resolve with a value. It is just a function that sets a timer for a function that (will run in window's context) and return 1. The returned value is not captured anywhere.
async function test(){
setTimeout(function(){return 1}, 100)
};
To access the value from setTimeout you will have to wrap it in a promise and let the promise resolve with that value.
async function test(){
return new Promise((resolve,reject) => setTimeout(function(){resolve(1);}, 100));
};
test().then(console.log);
async function test2(){
return 1;
};
test2().then(console.log); // Displayed
Another way to access value inside setTimeout, without using promises is to pass callbacks like below.
async function test(callback){
setTimeout(function(){callback(1)}, 100)
};
test(console.log);
The above code shows why it is easier to reason about code with promises. Any piece of code, which you want to have access to the value (from inside setTimeout) will have to be in the callback. This gets messy