Promise is something

Promise was a solution to asynchronous programming, primarily to solve the problem of asynchronous event callback hell. A Promise is simply a container that holds an event that will end in the future, that is, an asynchronous operation. Syntactically, a Promise is an object that can retrieve the results of an asynchronous operation. It also provides a unified API to express asynchronous operations as a flow of synchronous operations, avoiding layers of nested callback functions.

Promise the pros and cons

Advantages: As we have seen above, it can express asynchronous operations as synchronous operations, with nested layers of callback as.then().then()… , which makes code writing and reading more intuitive, and solves the problem of nested asynchronous operation callbacks.

Disadvantages: First, there is no way to cancel a Promise; once it is created, it is executed immediately and cannot be cancelled halfway through. Second, if you don’t set a callback function, errors thrown inside a Promise won’t be reflected externally. Third, when you are in a pending state, you have no way of knowing what stage of progress you are currently in (just beginning or just finishing).

Basic usage

ES6 specifies that a Promise object is a constructor that generates a Promise instance. The Promise constructor takes a function as an argument, resolve and reject. They are two functions that are provided by the JavaScript engine and do not need to be deployed themselves.

A Promise instance has these states

  • Pending: Indicates the pending status. justnewThe Promise that comes out is in this state; The statement defined in executor is then immediately executed
  • Resolved: Code is executingresolve()After the statement
  • Rejected: The code is executedreject()After the statement
  • Settled: Resolved or Rejected states are settled

The resolve function changes the state of the Promise object from “waiting” to “successful” (that is, from pending to Resolved), calls it when the asynchronous operation succeeds, and passes the result of the asynchronous operation as an argument. The Reject function changes the state of the Promise object from pending to Rejected. It is called when the asynchronous operation fails and passes the error reported by the asynchronous operation as a parameter.

After the Promise instance is generated, the then and catch methods can be used to specify the resolved state and Rejected state callback functions, respectively.

Simple implementation

  1. Promise is a constructor
  2. Promise internally defines the state of three property values (the initial state is pending, which cannot be changed once changed). The promise returns value value value on success and value reason on error
  3. A promise takes a function, resolve and reject, that changes the promise state
  4. Processor exector is executed immediately when the instance is initialized
  5. All promise instances have then methods, so then must be on the promise prototype
  6. The then method takes two arguments, calls back on success, calls back on failure, and executes if it is a method
  7. To handle asynchrony internally, a Promise needs to define two arrays
  8. If the promise is pending when it’s then, put the callback method in an array and call it resolve or Reject

Promise receives the results of a synchronous request (1-6 fur)

Pomise is a constructor
function Promise(exector) {}
Copy the code
// 2. Promise internally defines three attribute values: state (initial state pending, once changed, cannot be changed)
function Promise(exector) {
  this.state = 'pending';
  this.value = undefined;
  this.reason = undefined;
}
Copy the code
// 3. A promise accepts a function as an argument. The resolve and reject arguments are used to change the promise state
let p = new Promise((resolve, reject) = > {
    resolve('Front-end noob');
})
p.then(data= > console.log(data)) // Front-end noob
Copy the code
// 4. Processor exector is executed immediately when the instance is initialized
function Promise(exector) {
  this.state = 'pending';
  this.value = undefined;
  this.reason = undefined;
  
  exector(resolve,reject);
  // The executor is actually a function that promise accepts
  // Execute immediately
  // (resolve, reject) => {
  // resolve(' resolve ');
  //  }()
  
  function resolve(value) {
    if(that.state === 'pending') {
      that.value = value;
      that.state = 'resolved'; }}function reject(reason) {
    if(that.state === 'pending') {
      that.reason = reason;
      that.state = 'rejected'; }}}// Initialize the instance executor immediately
let p = new Promise((resolve, reject) = > {
    resolve('Front-end noob');
})
p.then(data= > console.log(data)) // Front-end noob
Copy the code
// 5. All promise instances have then methods, so then must be on the promise prototype
// 6. The then method takes two arguments, calls on success, calls on failure, and executes if it is a method

Promise.prototype.then = function (onFulfilled, onRejected) {
  // The then method has two callback functions that succeed and fail
    if(this.state === 'resolved') {/ / resolved state
      if(typeof(onFulfilled) === 'function'){
        onFulfilled(this.value); }}if(this.state === 'rejected') {/ / rejected state
      if(typeof(onRejected) === 'function'){
        onRejected(this.reason); }}}Copy the code

Promise receives the result of an asynchronous request (essence 7-8)

// 7. Promise internally needs to define two arrays to handle asynchrony
If the promise is pending then put the callback method in an array and call it resolve or reject
function Promise(exector) {
  this.state = 'pending';
  this.value = undefined;
  this.reason = undefined;
  
  this.onResolvedCallbacks = []; // Asynchronous callback succeeded
  this.onRejectedCallbacks = []; // Asynchronous failed callback
  
  let that = this;
  try{
   // The processor exector is immediately executed when the promise instantiates
    exector(resolve,reject); 
    // The executor is actually a function that promise accepts
    // (resolve, reject) => {
    // resolve(' resolve ');
    //  }()
  }catch(err) {
    console.log(err);
  }
  
  function resolve(value) {
    if(that.state === 'pending') {
      that.value = value;
      that.onResolvedCallbacks.forEach((cb) = > cb(value)); // Execute the callback in resolve
      that.state = 'resolved'; }}function reject(reason) {
    if(that.state === 'pending') {
      that.reason = reason;
      that.onRejectedCallbacks.forEach((cb) = > cb(reason)); // reject Execute the callback
      that.state = 'rejected'; }}}Promise.prototype.then = function (onFulfilled, onRejected) {
  // The then method has two callback functions that succeed and fail
  
    // Pending state processing
    if(this.state === 'pending') {
      if(typeof(onFulfilled) === 'function') {this.onResolvedCallbacks.push(onFulfilled);
      }
      if(typeof(onRejected) === 'function') {this.onRejectedCallbacks.push(onRejected); }}/ / resolved state
    if(this.state === 'resolved') {if(typeof(onFulfilled) === 'function'){
        onFulfilled(this.value); }}/ / rejected state
    if(this.state === 'rejected') {if(typeof(onRejected) === 'function'){
        onRejected(this.reason); }}}// The promise object takes a function as an argument. The resolve and reject arguments identify success and failure
let p = new Promise((resolve, reject) = > {
    setTimeout(() = > {
       resolve('Front end big big rookie');
    },1000)
})
p.then(data= > console.log(data)) // The front end is big
Copy the code

The class is used to implement

class Promise1 {
  // Instance properties and methods
  constructor(executor) {
    let that = this;
    this.state = 'pending';
    this.value = undefined;
    this.reason = undefined;
    this.onResolvedCallbacks = []; // Asynchronous callback succeeded
    this.onRejectedCallbacks = []; // Asynchronous failed callback

    executor(resolve, reject)

    function resolve(val) {
      if(that.state === 'pending') {
        that.value = val;
        that.onResolvedCallbacks.forEach(cb= > {
          cb(val);
        })
        that.state = 'resolved'; }}function reject(err) {
      if(that.state === 'pending') {
        that.reason = err;
        that.onRejectedCallbacks.forEach(cb= > {
          cb(err);
        })
        that.state = 'rejected'; }}}// Prototype method
  then(onFulfilled, onRejected) {
    if(this.state === 'pending') {
      if(typeof(onFulfilled) === 'function') {this.onResolvedCallbacks.push(onFulfilled);
      }
      if(typeof(onRejected) === 'function') {this.onRejectedCallbacks.push(onRejected); }}if(this.state === 'resolved' && typeof(onFulfilled) === 'function') {
      onFulfilled(this.value);
    }
    if(this.state === 'rejected' && typeof(onRejected) === 'function') {
      onFulfilled(this.value); }}}let p = new Promise1((resolve, reject) = >{
  setTimeout(() = > {
    resolve('Front End rookie');
  }, 10);
})
p.then(res= > {
  console.log(res); // Front-end noob
},err= >{
  console.log(err);
})
Copy the code

conclusion

This article is just an introduction to Promises, their pros and cons, and the simple implementation of promises. Chained calls and other methods of Promises will be updated in the future. If there is a wrong place to write please big guy to give directions I will correct the first time.