Execution of then() function in JavaScript
It works this way because of the way .then()
handlers are described in the promise specification.
All .then()
handlers are executed on a future tick of the event loop. That means that any synchronous code executes before any .then()
handler even if the promise is resolved immediately.
Here's a very simple example:
console.log("a");
Promise.resolve().then(() => {console.log("b");});
console.log("c");
This will output:
a
c
b
This is per the promise specification and it is done this way to guarantee that .then()
handler are ALWAYS asynchronous and thus have a consistent and predictable behavior, regardless of whether the promise is resolved immediately or some time in the future. It makes writing and testing code a lot simpler.
From the Promises A+ specification:
2.2.4 onFulfilled or onRejected must not be called until the execution context stack contains only platform code. [3.1].
"platform code" here means that the current execution of Javascript finishes and then when the stack is completely empty of any Javascript, then and only then are promises .then()
handlers called.
So, in my example above, the promise is resolved immediately, and the .then()
handler is scheduled immediately, but it is scheduled to run AFTER the rest of the synchronous code finishes (essentially on the next turn of the event loop).
In the ES6 specification, when a promise resolves, its .then()
handlers are scheduled with enqueJob()
. The concept of jobs in ES6 is described here. What's relevant here is that they run AFTER the currently executing Javascript is done.
What does .then(() = Storage.deployed()) actually mean in Javascript?
() =>
is an arrow function in Javascript.
Definition
An arrow function expression is a syntactically compact alternative to
a regular function expression, although without its own bindings to
the this, arguments, super, or new.target keywords. Arrow function
expressions are ill suited as methods, and they cannot be used as
constructors.
Read more about arrow functions
.then()
Definition:
The then() method returns a Promise. It takes up to two arguments:
callback functions for the success and failure cases of the Promise.
Read more about Promise.prototype.then()
What is happening is that when the deployer.deploy(Storage)
promise has resolved, you are then executing the function storage.deployed()
as a callback function.
How to use .then() in node.js?
.then
is a method that exists on Promises and is a mechanism for code synchronization. Your code is not asynchronous, so you wouldn't need to use promises. You can just call
one();
two();
three();
If your code does something asynchronous, then you can use promises and .then
. Asynchronous operations are things like reading/writing files, http requests, timers, and many more.
Just as an example, we can use the built in Promise
to create our own asynchronous operations:
I don't recommend you do this normally. We're just using it as an example. In most cases you can call functions that already return promises for you.
function one() {
return new Promise(resolve => {
console.log("one");
resolve();
});
}
function two() {
return new Promise(resolve => {
console.log("two");
resolve();
});
}
function three(){
console.log("three")
}
one().then(() => two()).then(() => three());
Also note that when you use .then
, you need to pass a callback. two()
calls the two
function immediately, so it's not the same as () => two()
.
Next, you can often use async
/await
instead of .then
which I think makes your code easier to reason about in most cases.
async function run() {
await one();
await two();
three();
}
run();
This is the same as the second example rewritten to use await
instead of .then
. You can think of everything after await
as being inside of a .then
chained to the expression after await
.
Finally, you should handle errors by either chaining .catch
to the promises or using the normal try
/catch
inside of async
functions.
Use of 'then' in ReactJS
fetchComments
returns a promise (probably; it could just be a "thenable"*). A promise is something that will be either resolved or rejected at a later point in time (typically**). then
is used to hook up a handler that will be called when the promise is resolved (and optionally when it's rejected, if you pass a second function into then
; otherwise you'd use catch
).
In this case, that code says that when/if the promise returned by fetchComments
resolves, use the resolution value to set the state of the React component using the comments
property of that resolution value.
More about promises in this MDN article and in the Promises/A+ spec.
* See the Promises/A+ spec for what a "thenable" is.
** If you use then
on a promise that's already resolved or rejected, you're guaranteed by the native promises in JavaScript that your handler will still be called asynchronously. That wasn't always the case with some early promise-like implementations, which would either call your callback asynchronously (if the promise wasn't already settled) or synchronously (if it was), which was...chaotic and unhelpful. JavaScript's native promises and any really good promise library guarantees consistent callback behavior.
does Javascript .then() function check for the promise in a web api
How is the then function able to check when the Promise object is resolved?
It doesn't. The then
method puts the callback on the promise's list of fulfillment callbacks, and then its job is complete. Later, when the promise is fulfilled, it's that code (fulfilling the promise) that puts calls to the promise's fulfillment callbacks in the microtask queue. (You're right though that it's then
that does it when the promise is already fulfilled when then
is called.)
await
works the same way, since await
is "just" syntactic sugar for then
. (That "just" skips over a lot of details, though. :-D )
Side note: You'll notice I said "fulfillment callbacks," not "resolution callbacks," and referred to the promise being fulfilled (not resolved). There's a big difference between "fulfilled" and "resolved," but unfortunately it's not well understood and people use "resolve" where they mean "fulfill" a lot. See my blog post here (which the MDN folks linked from their documentation) for the difference (and why it matters). (That said, if you say you "resolve the promise with X" and X isn't a promise or other thenable, that's basically synonymous with "fulfill the promise with X." That's not true when X is a promise or other thenable.)
What is the (function() { } )() construct in JavaScript?
It’s an Immediately-Invoked Function Expression, or IIFE for short. It executes immediately after it’s created.
It has nothing to do with any event-handler for any events (such as document.onload
).
Consider the part within the first pair of parentheses: (function(){})();
....it is a regular function expression. Then look at the last pair (function(){})();
, this is normally added to an expression to call a function; in this case, our prior expression.
This pattern is often used when trying to avoid polluting the global namespace, because all the variables used inside the IIFE (like in any other normal function) are not visible outside its scope.
This is why, maybe, you confused this construction with an event-handler for window.onload
, because it’s often used as this:
(function(){
// all your code here
var foo = function() {};
window.onload = foo;
// ...
})();
// foo is unreachable here (it’s undefined)
Correction suggested by Guffa:
The function is executed right after it's created, not after it is parsed. The entire script block is parsed before any code in it is executed. Also, parsing code doesn't automatically mean that it's executed, if for example the IIFE is inside a function then it won't be executed until the function is called.
Update
Since this is a pretty popular topic, it's worth mentioning that IIFE's can also be written with ES6's arrow function (like Gajus has pointed out in a comment) :
((foo) => {
// do something with foo here foo
})('foo value')
Related Topics
Sum of Array Object Property Values in New Array of Objects in JavaScript
Jquery.Getjson - Access-Control-Allow-Origin Issue
JavaScript Infinitely Looping Slideshow with Delays
Prevent Jquery UI Dialog from Setting Focus to First Textbox
How to Stop a Window.Setinterval in JavaScript
Secure Random Numbers in JavaScript
"Var" or No "Var" in JavaScript's "For-In" Loop
Access-Control-Allow-Origin Denied Spotify API
Detect iPad Users Using Jquery
Validate That a String Is a Positive Integer
How to Merge Two JavaScript Objects Together in Es6+
Browser Event When Downloaded File Is Saved to Disk
How to Inherit Old-Style Class from Ecmascript 6 Class in JavaScript
Vuejs and Vue.Set(), Update Array