Reputation: 2543
I'm trying async/await functionality. I have such code imitating a request:
const getJSON = async () => {
const request = () => new Promise((resolve, reject) => (
setTimeout(() => resolve({ foo: 'bar'}), 2000)
));
const json = await request();
return json;
}
When I use the code in this way
console.log(getJSON()); // returns Promise
it returns a Promise
but when I call this line of code
getJSON().then(json => console.log(json)); // prints { foo: 'bar' }
it prints json as expected
Is it possible to use just code like console.log(getJSON())
? What don't I understand?
Upvotes: 77
Views: 71154
Reputation: 12395
Other answers already explain "Every async function returns a Promise object" but I guess the confusion may also come from the fact that you always need to write await
twice, one inside the async function implementation (getJSON()
in your case) and one for the caller of that async function.
This is a common point of confusion, e.g. Why do I have to call await twice in order to get the promise resolved?
Except for the return value is a promise, Control flow effects of await in MDN can further explain,
When an await is encountered in code (either in an async function or in a module), the awaited expression is executed, while all code that depends on the expression's value is paused and pushed into the microtask queue. The main thread is then freed for the next task in the event loop. This happens even if the awaited value is an already-resolved promise or not a promise.
Because "all code that depends on the expression's value (inside the async function) is paused and pushed into the microtask queue", the caller of the async function also needs to await (to get the awaited result in the async function).
BTW, one answer here said "if you want your async function to return a value immediately you can use Promise.resolve" is wrong in Returning an awaited value returns a Promise? (es7 async/await) even though it got some upvotes.
Upvotes: -1
Reputation: 54
const getResOrErr = () => {
const callAsyncCodeHere = async () => {
const request = () =>
new Promise((resolve, reject) =>
setTimeout(() => resolve({ foo: "bar" }), 2000)
);
const json = await request();
return json;
};
return callAsyncCodeHere()
.then(console.log)
.catch(console.log);
};
getResOrErr();
Try this. You can achieve making a function inside your main function and then put you promise code inside that function. Call it there and when you get the response or error just return it.
Upvotes: -1
Reputation: 557
A function defined with async
always returns a Promise
. If you return any other value that is not a Promise
, it will be implicitly wrapped in a Promise
. The statement const json = await request();
unwraps the Promise
returned by request()
to a plain object { foo: 'bar' }
. This is then wrapped in a Promise
before being returned from getJSON
so a Promise
is what you ultimately get when you call getJSON()
. So to unwrap it, you can either call getJSON().then()
like you've done or do await getJSON()
to get the resolved value.
Upvotes: 7
Reputation: 3739
Return value of an async function will always be an AsyncFunction Object, which will return a Promise
when called. You can not change that return type. The point of async/await
is to easily wait for other async process to complete inside an async function.
Upvotes: 5
Reputation: 10512
Every async
function returns a Promise
object. The await
statement operates on a Promise
, waiting until the Promise
resolve
s or reject
s.
So no, you can't do console.log
on the result of an async function directly, even if you use await
. Using await
will make your function wait and then return a Promise
which resolves immediately, but it won't unwrap the Promise
for you. You still need to unwrap the Promise
returned by the async
function, either using await
or using .then()
.
When you use .then()
instead of console.log
ging directly, the .then()
method makes the result of the Promise available to you. But you can't get the result of the Promise
from outside the Promise. That's part of the model of working with Promises.
Upvotes: 106