Search code examples
javascriptfunctionasynchronouspromiseexecution

The execution order of the promise according to the return type 2


This question is similar to my previous "The execution order of the promise according to the return type", but it is a little different.

Why is the order of execution of caseA and caseB different?

The difference between the code is "return" or "return promise"

caseA: 914258367

<html>
<head>
<script>
var promise = Promise.resolve();    
    
promise = promise.then(function(rtnVal) {   
    console.log('1');
    var promise2 = Promise.resolve();
    promise2 = promise2.then(function(rtnVal) {
        console.log('2');
    });
    promise2 = promise2.then(function(rtnVal) {
        console.log('3');
    });
    console.log('4');
    return;
}); 
    
promise = promise.then(function(rtnVal) {   
    console.log('5');
    var promise2 = Promise.resolve();
    promise2 = promise2.then(function(rtnVal) {
        console.log('6');
    });
    promise2 = promise2.then(function(rtnVal) {
        console.log('7');
    });
    console.log('8');
    return;
}); 
    
console.log('9');   

</script>
</head>
</html>

caseB: 91423 -> 5,6,7,8 don't even run

<html>
<head>
<script>
var promise = Promise.resolve();    
    
promise = promise.then(function(rtnVal) {   
    console.log('1');
    var promise2 = Promise.resolve();
    promise2 = promise2.then(function(rtnVal) {
        console.log('2');
    });
    promise2 = promise2.then(function(rtnVal) {
        console.log('3');
    });
    console.log('4');
    return promise;
}); 
    
promise = promise.then(function(rtnVal) {   
    console.log('5');
    var promise2 = Promise.resolve();
    promise2 = promise2.then(function(rtnVal) {
        console.log('6');
    });
    promise2 = promise2.then(function(rtnVal) {
        console.log('7');
    });
    console.log('8');
    return promise;
}); 
    
console.log('9');   

</script>
</head>
</html>

Solution

  • In the 2nd example, promise in return promise; in the 1st then method call fulfillment handler refers to the promise returned by the 2nd then method call.

    This creates a situation where the promise returned by the 2nd then method (let's call it p2) waits for the promise returned by the 1st then method (let's call it p1) to settle. In short, p1 is waiting for p2 to settle, and p2 is waiting for p1 to settle, creating a deadlock.

    This prevents the 2nd then method fulfillment handler from getting invoked because promise, i.e. p1 never fulfills.

    Following code is a simplified version of what your code is doing:

    const p1 = Promise.resolve();
    
    const p2 = p1.then(() => p3); // p2 will always be in pending state
    
    const p3 = p2.then(() => console.log("done")); // fulfillment handler never called
    

    The fulfillment of p2 in the above code example depends on the return value of the p1.then(...) method. But the value being returned is p3, and p3 is waiting for p2 to settle. This puts the code in a situation where p2 is waiting for p3 to settle, and p3 is waiting for p2 to settle, creating a deadlock.