<script>
function myDisplay2() {
let myPromise = new Promise((resolve, reject)=>{
resolve(1);})
let myPromise2 = myPromise.then(setTimeout(()=>{
console.log(myPromise); // first then()
return new Promise((resolve, reject)=>{
resolve(2);});
}, 10000));
let myPromise3 = myPromise2.then(()=>{console.log(myPromise2)}); // second then()
}
myDisplay2();
</script>
I use setTimeout to simulate an asynchronous call.
In the console, the output is second then() run first, and the PromiseResult is 1, then first then is run, PromiseResult is 1 also.
why second then() is run before first then() is resolved?
how to modify to make second then() run after first then() is resolved?
let myPromise2 = myPromise.then(setTimeout(()=>{
console.log(myPromise); // first then()
return new Promise((resolve, reject)=>{
resolve(2);});
}, 10000));
Should be
let myPromise2 = myPromise.then(() => {
return new Promise((resolve,reject) => {
setTimeout(()=>{
console.log(myPromise);
resolve(2);
}, 10000)
});
});
The then statement needs to return a new Promise immediately (well, at the end of its processing, but you get what i mean), if its going to, so that the next then knows what to wait for.
yes, following your change, the output is first then () run first, and second then() will run after first then().
But is this really necessary that then() statement needs to return a new Promise immediately? As its API has not mentioned such requirement.
soâŚwhat is the consequence? I cannot catch your ideaâŚor you mean my origin code, setTimeout() has no return type and so nothing to wait for return?
soâŚyes, setTimeout returns an identifier which can be used to clear the timer.
The important concept is that setTimeout is effectively an asynchronous call. In the strictest terms, itâs not - the thread stops, and waits for setTimeout to return a value - but that value (the identifier) is returned near instantaneously, and the thread continues. It DOES NOT wait for the timer to expire and retrieve the result from the called procedure.
So⌠my example may have been slightly off. Itâs not equivalent to console.log, itâs equivalent to var x = 3;. Is everybody happy now with what type of thing gets spit out of a null-effect statement?
This return IS specified in the MDN:
For the purposes of timing, an uncaught and unreturned setTimeout is a no-op. So your script as originally written for mypromise.then goes:
Wait for myPromise to Resolve or Reject.
NoOp;
Return Promise(resolve(undefined))
If you had returnâd the setTimeout, youâd have returned the value of the handle, and the MDN specifies that:
What you are trying to do, and what is also spelled out in the MDN, is the last return rule:
It has to evaluate these rules when the thread leaves the function. Because setTimeout does not halt the thread (except for the microsecond or so it spends figuring out what the handle is), it is immediate, and must be evaluated at that time.
quite lost, âsetTimeout is effectively an asynchronous callâ, chaining then() is not used to force one asynchronous call inside then() finished before the next then()?
Inside the first then() is a asynchronous call (setTimeout()), why the second then() not wait it finished?
The rough gist of it. setTimeout and promise callbacks end up on two different queues. setTimeouts on the callback queue and promises on the microtask queue. The event loop prioritizes microtask queued callbacks over the callback queueâs.
I believe âasyncâ and âawaitâ will solve this problem.
They are also far easier to understand and chain together; plus they have other additional capabilities.
You canât await a setTimeout - it returns a value immediately (the handle), so thereâs nothing to wait for.
You could sleep(10000) though, sure, if you donât mind your main javascript thread being held up in the meantime, which is sort of what Promises were designed NOT to have to do.
Await says âNormally, I set this thing going and forget about it. But now iâll wait for it to come back and see what it says.â
A Promise is âIâm setting this thing going, but whenever it gets done, I want to know about it, because I have things to do.â
setTimeout is âI want to do some things at a fixed time from now.â
Or my origin sample is this case? it returns a value immediately (the handle), and the first then() âgets resolved immediately with the returned value (the handle) as its valueâ? but if this is the case, the second then() (the value of myPromise2) should return the handle value, not 1âŚ
then my origin question case is the same as the following mentioned in MDN?
If one or both arguments are omitted or are provided non-functions, then then will be missing the handler(s), but will not generate any errors. If the Promise that then is called on adopts a state ( fulfillment or rejection ) for which then has no handler, the returned promise adopts the final state of the original Promise on which then was called.
âthe Promise that then is called on " is myPromise in my quesiton. " the returned promise adoptsâŚâ is myPromise2 in my quesiton?
And the âgets resolved with an undefined value.â is happened immediately?
then takes two parameters: a function to execute when the result of the promise itâs called upon was a success, and a function to execute when the result of the promise itâs called upon was a failure.
In the below example, we do not generate/define a function for the failure state. mypromise.then(() => { var x = 3; doSomeStuff(x); })
if mypromise is resolved , then executes the function we have defined, and returns a new Promise that satisfies the rules listed in MDN, depending on the return value of our function (in this case, it would be a resolved Promise with value undefined)
if mypromise is rejectâd, there is no function defined to handle the rejection (there is no second parameter in our then), so then returns a new, rejectâd, Promise, with whatever value was in the rejection from mypromise (In other words, it propagates the rejection)
correct. var x = myPromise.then(), myPromise is the âpromise the then is called onâ and x, after execution, will contain the âreturned promiseâ.
If the promise would be resolved , it would be immediate. (All rules return a resolved promise, with the exception of the one that returns a pending promise.)