When you call this terminate()
which is this:
function terminate() {
setTimeout(() => console.log("Edning"), 1)
}
The setTimeout()
pushes it’s callback to a future cycle of the event loop and EVERYTHING else in the current cycle of the event loop runs before it. Only when the current chain of code has finished and control has returned back to the event loop will the setTimeout()
get a chance to run its callback.
So, here’s the sequence of what happens in your code:
call()
is executed.myprom()
is executed. That resolves its promise immediately so it will schedule it’s.then()
handlers to run as soon as control returns back to the event loop..then()
and.catch()
run. All they do at this point is register some callbacks to be called later when the promise is ready to execute them.- Your async function returns and control goes back to the event loop.
- The already resolved promise is first in line in the event loop so it gets control and executes it’s
.then()
handler. myfunc(1)
runs and that outputsStarting in 1
console.log(result)
runs and that outputsI Promise to end without showing next line
terminate()
runs and that sets a timer for 1ms from now. That function returns and the timer is schedule to run on a future tick of the event loop when 1ms has passed.dummy(1)
is called and that outputsI am not supposed to print anything
.terminate()
is called again and that again schedules another timer to run in 1ms on a future tick of the event loop.- The
await
processes the promise and resolves the promise that theasync
functioncall()
returns. Theawait
does nothing useful here and there’s nothing listening for the promise thatcall()
returns either. - Control is returned back to the event loop.
- The first timer you set with the first call to
terminate()
gets to run and it outputs. That returns control back to the event loop. - The second timer you set with the second call to
terminate()
gets to run and it puts. That returns control back to the event loop and everything associated with this code is done.
In general. how to stop js execution abruptly inside .then object?
If what you’re asking is how you skip the other functions you call all in a row, then you would typically use conditionals to branch of return
early out of the .then()
callback. For example, you could do this:
async function call() {
await myprom("to end without showing next line")
.then(result => {
myfunc(1) // Call # 1
console.log(result) // Call # 2
if (result === "I Promise to end without showing next line") {
// skip the rest of the code in this callback
return;
}
terminate() // Call # 3
dummy(1) // Call # 4
terminate() // Call # 5
})
.catch(err => {
console.log(err)
})
}
call()
Since you’re in a .then()
handler, you could also so a throw someError
and that would abruptly stop the .then()
handler just like throwing any exception aborts the execution of the current function. Because this is in a .then()
handler that exception will be immediately caught and will then execute the .catch()
handler and pass it the exception you threw. This wouldn’t typically be used for a normal execution path because this more typically indicates some error condition. A normal execution path would more likely catch the condition locally and use branching or if/else
logic or something like that to decide what code in the function executes next.
Note, if you’ve already started some timers, then to keep them from firing, you would have to save the timerID
that setTimeout()
returned and use clearTimeout()
on that timerID
to cancel the timer.
If you really want abrupt stopping to stop your whole process, then in node.js, you can also call process.exit()
.
It’s unclear why you thought the output from dummy(1)
and the second call to terminate()
would not show in the output? You called dummy(1)
. Nothing in the terminate()
function causes Javascript to skip the rest of the code in the .then()
handler. So, it continues and executes both dummy(1)
and the second terminate()
and thus you see the output from both.