The JavaScript Promise | Simplified 
Published: 2019-12-31 03:27:02



## What is the JavaScript Promise? 

 Let's start at the base level.
*    1. The top-level "**[Promise]**" is a JS built-in (native) object.
*    2. It is a '*constructor function*' which, like most objects in JS, has a 
        **prototype** (object) **property** on it which points to an object. This 
        object contains a "template" or "bucket" of properties and 
        values(key/value pairs). One of those properties is a **constructor** 
        whose value references the Promise constructor 'function' itself.  The 
        Promise's prototype object **(Promise.prototype)** can be 
        accessed/referenced by newly created *instance*(child)*objects* of the 
        parent object, Promise. 
*     3. The JavaScript Promise allows one to handle asynchronous operations in 
         an otherwise synchronous, single-threaded(top-down), and non-blocking 
         environment.

Putting it all together: A Promise is an object, which is a constructor function, that acts like a wrapper around other functions, whose purpose is to 'promise' a return value not yet known, in an asynchronous environment. 

## A Promise has three states:

*    1. Pending: The inital state, it's neither fulfilled, nor rejected.
*    2. Fulfilled: Successful.
*    3. Rejected: meaning that the operation failed. 

The JS Promise syntax:  **Promise(executor)**

>When a 'new Promise()' is invoked by the JS Engine, it creates a new Promise{} object, and the '*executor*' is run **automatically**. The executor has two arguments which are '**resolve**' and '**reject**'. These are *callback* *functions*. The executor function **first does it's job and obtains the result, be it sooner or later, it then calls on one of these callbacks depending on the executors' result.**
   
The '*executor*' is a function which takes two arguments, it's parameters are;

1. Parameter one: '**resolve**'    
 resolve(value)  : value is either (1) *state*: fulfilled, or (2)*result*: value.
2. Parameter two: '**reject**'  
 reject(error)   : *state*: 'rejected', or *result*: error.
 
The ES5 function declaration:  
    <pre><code>Promise(function(resolve,reject){};</pre></code>
The ES6 Arrow Function declaration:
    <pre><code>Promise((resolve,reject) => {
               resolve( //resolve someThing placed in here. );
               reject(// if not resolved; do this.);
});</pre></code>

The *'executor function'* is invoked **immediately** even before the 'Promise' constructor returns the instance object. (This is a [Promise] built-in functionality)

>The parameter's '*resolve*' and '*reject*' are ordered inside the parentheses. So, the **first parameter** tests for 'truthy'. And, the **second parameter** tests for 'falsy'. 

>The parameters can be changed to any wording you like; however, conventional useage is encouraged by using 'resolve' and 'reject'. 



### The constructor syntax for creating a new promise object.

*    1. Create a variable using either the **let** or **const** statement which 
     declares a block-scoped variable. The difference in the two keywords is that 
     the 'value' of **const** cannot be changed or re-declared. The *const* value     can however be 'mutated. This can be rectified by using the ES6 Object.freeze() method.
 

```
let x = 5;  //globally scoped
   
    function foo(){
        let x = 'I am x!, scoped local to this block';  //locally scoped
        console.log(x);  // 'I am x!, scoped local to this block'
     };
console.log(x) // 5
foo();  // 'I am x!, scoped local to this block'
```

*    2. Using '*new Promise()*' creates an instance object of the 
        [Promise] object.
        
>    a. The **new** operator will create a blank object: Promise{}.
>    b. It links up(sets) the constructor of one object 
        (Promise.prototype.**constructor**) to another 
        object's constructor(the newly created instance object (*p*) of Promise; 
        *p*. __ proto __.**constructor**.) 
>    c. It passes the newly created object (**Promise {}**) as the **'this'** 
        context. For instance when creating(defining) properties in the 
        constructor function Promise's code block, we use the **this** keyword to
        point to the parent object 'Promise' as we instantiate the property 
        members.
        
*    3. The constructor function **Promise** and, *resolve* and *reject*.  

A simplified use of a Promise for the purpose of explaining the resolve and reject methods (functions). 

```
let p1 = new Promise((resolve, reject) => {
         
         //set x to the sum of two numbers.
          let x = 10 + 5;
         
         //if statement and strict equality operator
           if(x === 15) {
                resolve('x is 15');
           }else{
                reject('error: x is not 15')
           }
});
``` 
          

*    4. Now we 'use' the newly created instance (child) object, *p1*.
        We use the Promise.prototype.**then()** method(function) to return a 
        [Promise]. 
  
      The '**.then()** method takes up to two arguments that are 'callback 
      functions' for resolve(success) or the rejected(failure) methods.

> The MDN syntax for the Promise.prototype.then() method is;

```
p.then(onFulFilled [, onRejected]);

p.then(value => {
    // fulfillment
}, reason => {
    // rejection
});
```
 

        
* Using an 'asynchronous' operation with a new promise.
```
let p2 = new Promise((resolve, reject) => { 
 
    //creating a 'asyn' condition for test purposes
    setTimeout(() => {
        resolve('I have been resolved!');
        reject('Failed.');
     }, 3000)  //3000 milliseconds or 3 seconds
});
```


>Now, let's test it!

```
p2.then((val) => {
  console.log(val)   
},(error) => {
  console.log(error);
});
```

When the code is invoked there is a lot initially going on under the hood, but I want to try to keep my explanation short for the code snippet above.

1. The let variable 'p2' is placed in global memory by the JS engine.
2. The JS engine continues to parse the same line of code and sets the 'constructor function' identifier(name) **'Promise'** with 'new' in global memory and as a copy with it's function definition and it's two parameters, resolve and reject. 
(The engine does not do anything but record the inner function definition, the **setTimeout()** method.)
3. The JS engine next reads the 'p2' and trys to find it. It does. Then the JS engine sees the assignment operator (=) and knows that there is a right-operand. It continues on parsing the right operand; the **new Promise()**. It finds 'Promise' in it's global memory. The parentheses after the 'Promise' inform the JS engine to invoke(execute/run) the Promise(executor)function. The 'executor' function first does it's job,then based on the result, calls one of the callback function's; either resolve and reject. 
4. When the inner function, 'setTimeout' is invoked, the JS engine creates a whole new '*execution context*' for the function. And, the function gets placed on the call-stack on top of the *Promise()* function, and others if still pending. 
(Sorry, I don't have room for explaining the heap, stack, WebAPI'S, event loop, or the callback queue. All important topics on their own).  
5. Once a promise is fulfilled or rejected the appropriate handler, either the 'onFulFilled' or the 'onRejected' will run 'asynchronously'.
6. The 'then()' method basically says, 'return my promise'. 
7. The 'then()' method is also used for method chaining. (To be covered in my next post)


> We can also use the 'catch()' method of the parent object: [Promise].
Instance objects have access to the properties and methods on the parent object - Promise, through the prototype-chain. 



Thank you for taking time out to read my post. I am a self-taught web developer. So, when you find my mistakes...please inform so that I can correct and better yet...continue to learn from them.

TC