Reputation: 682
I am confused with certain parts regarding promises, I have read multiple articles and I have seen multiple videos and I want to ask a few things:
from what I understand currently, when a promise is created is starts running.
Do I need to await on the promise if the value that returned from the promise is not used in the code ?
a scenario for that is: let's say I am processing a task in my system and I want to log the information to mongodb, when I invoke the insert function I get a promise back. the execution beings but I don't care about the result of it
if I am not awaiting and there is an error I wouldn't be able to handle it.
A followup question to the question above:
from what I read whenever I await
it actually blocks the execution of the async function, but if it blocks the execution of the function how doesn't it block the rest of the eventloop ?
Upvotes: 1
Views: 586
Reputation: 4819
The whole point of the event loop is to have many microtasks that do not affect each other (hence by default there is no effect).
To chain microtasks first; there were callbacks, then Promises (then
/catch
) then the async
/await
API. The last two can be considered just syntactic sugar atop the callback concept. There are no 'functionalities' added but rather a different syntax to achieve the same stuff in simpler and more elegant ways (Pyhilosophicaly).
The event loop executes all the queued microtasks at each loop and repeats. Unless you have blocking code (and await
is not to be considered blocking) your event loop never stalls and hence other tasks are not affected.
You are trying to understand await
from the perspective of real blocking code as intended in other languages.
IMHO you first need to deeply understand how callbacks work, then study Promises (as a tool to make callbacks less messy) and then async
/await
(as a syntax to make Promises pretties). But keep in mind, the underlying system is the same: functions that call functions that get handled functions to be eventually called in future).
Yes, but no. A promise does not run, a promise is only a contract you receive by a part of code that will be used to notify you of the outcome. So the promise does not run, is the mean that has been created for you after you requested a task to be executed.
So typically if a promise has been handled to you there is something 'running'. But Promise
may be used differently and there may be something 'waiting'.
A promise is not linked to the execution of the task hence it can not start nor stop it.
No, you are not required to. But keep in mind that not handling promise exceptions is being deprecated and may result in system failure. You should always handle (or let bubble) exceptions.
There would be a failure if there is an unhandled promise rejection. In synchronous code this is equivalent to an uncaught thrown error. Until now(-ish) uncaught promise rejections were tolerated but there isn't a really good reason for that. Node is moving to treat them the same as any other error that bubbles to the top.
You are considering promises only with async
/await
but the underlying Promise
api is .then()
and .catch()
. Using this API you can use promises in a 'fire-and-forget' fashion:
async function Do() {
await before();
asyncDbCall().catch(err => console.error(err))
await after();
}
In this example you are not waiting for asyncDbCall()
but still .catch(err => console.error(err))
will result in the error being logged (some time in the future, probably even after Do()
has completed).
Or you can branch off the execution to other async executions, take this complex example:
async function Do() {
await before();
// This will execute AFTER before() & only if before() succeeded
asyncDbCall()
.then(async value => {
// This will execute after `asyncDbCall()` and only if it succeeded
await something(value);
// We reach here after `something()` and only if succeeded
})
.catch(err => {
// This will execute if `asyncDbCall()` fails of IF ANYTHING
// within `async value => {}` fails
console.error(err);
})
// This will execute AFTER before() and only if before() succeeded and
// asyncDbCall() call (but not Promise) succeeded
await after();
}
Await stops the async
function (hence also anything that is awaiting for the function) but does not affect anyway the event loop.
Upvotes: 6
Reputation: 2161
from what I understand currently, when a promise is created is starts running.
It is not. It has its internal state set to pending
. Promise's constructor takes a callback as an argument, and in turn provides it with resolve
and reject
callbacks.
What it also does is that it allows to provide a number of actions that
happen when it's state changes to resolved
or rejected
. Outside of async/await
, you might know them as .then
and .catch
instance methods of Promise
class. Once the state is changed, they will be executed.
Do I need to await on the promise if the value that returned from the promise is not used in the code?
No, that is entirely up to you.
a scenario for that is: let's say I am processing a task in my system and I want to log the information to mongodb, when I invoke the insert function I get a promise back. the execution beings but I don't care about the result of it
if I am not awaiting and there is an error I wouldn't be able to handle it.
You can still use .catch
to handle the error without awaiting for the Promise
to finish
A followup question to the question above:
from what I read whenever I await it actually blocks the execution of the async function, but if it blocks the execution of the function how doesn't it block the rest of the eventloop?
Promises have nothing to do with the event loop.
You can read more about the EventLoop here.
Upvotes: 0