简体   繁体   中英

Promises and Order of Operations

Apologies if this is a basic concept. I'm new to Javascript.

I'm trying to understand the order of execution of the following functions. I setup a Promise with 2 callbacks and a Promise with 3 callbacks right after.

function getSum(n1, n2){
    var isAnyNegative = function() {
        return n1<0 || n2 < 0;
    }
    var promise = new Promise(function(resolve, reject) {
        if (isAnyNegative()){
            reject(Error('Negative not supported'));
        }
        resolve(n1 + n2)
    });
    return promise;
}

// Double Promise
getSum(5,6).then(function(result) {
  console.log('DL1 '+result);
  return getSum(10,20);
}, function(error){
  console.log(error);
}).then(function(result) {
  console.log('DL2 '+result);
}, function(error){
  console.log(error);
});

// Triple Promise
getSum(5,6).then(function(result) {
  console.log('TL1 '+result);
  return getSum(10,20);
}, function(error){
  console.log(error);
}).then(function(result){
  console.log('TL2 '+result);
  return getSum(30,40);
}, function(error){
  console.log(error);
}).then(function(result){
  console.log('TL3 ' +result);
}, function(error){
  console.log(error);
});

The output was as follows (DL=>Double Layer, TL=>Triple Layer):

DL1 11
TL1 11
DL2 30
TL2 30
TL3 70

It would have expected the output to be Double Layer then Triple Layer however that's not the case. I looked into Hoisting but what I've read about it, it should at least protect the order of execution within the script. How are these functions ordered and why are they not executed in order of appearance?

If there's any more detail required please ask, Apologies and Thanks in Advance.

When running promises, each of the .then handlers run asynchronously as explained by https://javascript.info/microtask-queue

Basically for your code it means

  • The main code is run first, DL1 is queued, and TL1 is queued
  • As the execution of the main code ends, DL1 is first in queue so it executes and queues DL2
  • When the engine finishes with DL1, it takes the next queued item; TL1, which executes and queues TL2.
  • Now the next item in queue is DL2, and the remaining TLs follow

If you really need the promises to resolve DLs first, then TLs, then you need to make them part of the same promise chain

The order of execution from your example is correct.

When it comes to asynchronous operations (Promises), the whole concept is a bit different with synchronous operations.

In the explanation below, you can assume Promise as if it is a schedule/queue to run operations.

Use this simplified code for example:

 function sum(a, b){ return new Promise(function(resolve, reject){ if (a < 0 || b < 0) reject(new Error('Negative not supported.')); else resolve(a + b); }); } /* Double layer */ sum(5, 6).then(function(result){ console.log('DL1', result); return sum(10, 20); }).then(function(result){ console.log('DL2', result); }).catch(function(error){ console.error(error); }); /* Triple layer */ sum(5, 6).then(function(result){ console.log('TL1', result); return sum(10, 20); }).then(function(result){ console.log('TL2', result); return sum(30, 40); }).then(function(result){ console.log('TL3', result); }).catch(function(error){ console.error(error); }); 

If we follow the example above, the execution queue would look something like:

  1. Declare function sum .
  2. Run function sum(5, 6) as DL.
  3. Returns a Promise (DL), execution of sum (DL) ended.
  4. Run function sum(5, 6) as TL. Promise DL is running in background.
  5. Returns a Promise (TL), execution of sum (TL) ended. Promise DL is resolved in the background.
  6. DL1 .then() is run because Promise DL was resolved in step 5. Promise TL is resolved in the background.
  7. TL1 .then() is run because Promise TL was resolved in step 6. DL1 is resolved in the background.
  8. DL2 .then() is run because Promise DL1 was resolved in step 7. Promise TL1 is resolved in the background.
  9. ... (you get the idea)

As you can see, with Promises, some operations were run in the background. Which is why you will see the order of execution may not appear like how it is appeared.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM