let p = new Promise ((resolve,reject) = >{
	resolve('success');
	reject('fail');
})
p.then(data= >{},fail= >{})
Copy the code

According to the basic use of the above Promise, the analysis is as follows:

  • Promise is a constructor
  • A Promise receives a function that executes immediately and takes two arguments, resolve and reject
  • Promise has 3 types of state pending, depressing and Rejected
  • The resolve function changes the state from pending to depressing, and the reject function changes the state from pending to Rejected. Once the state becomes depressing or Rejected, the state cannot be changed
  • The then method takes two function arguments, executes the first on success, rejects the second on failure, and passes the resolve and reject arguments to the corresponding function
const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';
class myPromise{
  constructor(execute){
    execute(this.resolve,this.reject)
  }
  status = PENDING;
  successParams = undefined;
  failParams = undefined;
  resolve = (value) = >{
    if(this.status ! == PENDING)return;
    this.status = FULFILLED;
    this.successParams = value;
  }
  reject = (error) = >{
    if(this.status ! == PENDING)return;
    this.status = REJECTED;
    this.failParams = error;
  }
  then = (successCallback,failCallback) = >{
    if(this.status === FULFILLED){
      successCallback(this.successParams)
    }
    if(this.status === REJECTED){
      failCallback(this.failParams)
    }
  }
}
Copy the code

If the Promise immediately function has an asynchronous method, then the then function cannot execute immediately, as shown below:

let p = new myPromise((resolve,reject) = >{
  setTimeout(() = >{
    resolve('sucess');
  },2000);
})
Copy the code

Workaround: Store the two methods of the THEN function and wait for resolve or reject

class myPromise{... successCallback =undefined;
  failCallback = undefined;
  resolve = (value) = >{...this.successCallback && this.successCallback(value);
  }
  reject = (error) = >{...this.failCallback && this.failCallback(error)
  }
  then = (successCallback,failCallback) = >{...if(this.status === PENDING){
      this.successCallback = successCallback;
      this.failCallback = failCallback; }}}Copy the code

A Promise can also invoke multiple then methods at the same time, such as:

p.then(data= >{
  console.log(1)
  console.log(data)
},error= >{
  console.log(error)
})

p.then(data= >{
  console.log(2)
  console.log(data)
},error= >{
  console.log(error)
})
Copy the code

If the Promise is executed immediately, it is synchronous and does not need to be changed. If it is asynchronous, it needs to be changed.

Store the two functions in an array in then and wait until resolve and reject are executed


class myPromise{... successCallback = []; failCallback = []; resolve =(value) = >{...//this.successCallback && this.successCallback(value);
    while(this.successCallback.length) this.successCallback.shift()(value)
  }
  reject = (error) = >{...// this.failCallback && this.failCallback(error)
    while(this.failCallback.length) this.failCallback.shift()(error)
  }
  then = (successCallback,failCallback) = >{...if(this.status === PENDING){
      this.successCallback.push(successCallback);
      this.failCallback.push(failCallback); }}}Copy the code

Promise chain call

p.then(data= >{
  console.log(data)
  return 100
}).then(data1= >{
  console.log(111)
  console.log(data1)
})
Copy the code

Synchronization idea:

  • Then returns only a Promise object in order to continue calling then
  • The return value of the previous THEN is used by the next THEN
class myPromise{... then =(successCallback,failCallback) = >{
    let p2 = new myPromise((resolve) = >{
      if(this.status === FULFILLED){
        let x = successCallback(this.successParams);
        resolve(x)
      }
      if(this.status === REJECTED){
        failCallback(this.failParams)
      }
      if(this.status === PENDING){
        this.successCallback.push(successCallback);
        this.failCallback.push(failCallback); }})returnp2; }}Copy the code

Promise then The first function returns either a normal parameter or a Promise object (synchronization)

function testPromise(){
  return new MyPromise((resolve,reject) = >{
    resolve(2)
  })
}
p.then(data= >{
  console.log(data)
  return testPromise()
}).then(data1= >{
  console.log(111)
  console.log(data1)
})
Copy the code

Ideas:

  • If a normal argument is returned, it is used directly by the next THEN
  • If a Promise object is returned, the successful argument is returned to the first function of the next THEN, and the failed argument is returned to the second function
class MyPromise{... then =(successCallback,failCallback) = >{
    let p2 = new MyPromise((resolve,reject) = >{
      if(this.status === FULFILLED){
        let x = successCallback(this.successParams);
        promiseResolve(x,resolve,reject)
      }
	     ...
    })
    returnp2; }}function promiseResolve(x,resolve,reject){
  if(x instanceof MyPromise){
    x.then(resolve,reject)
  }else{
    resolve(x)
  }
}
Copy the code

Promise then(the first function) cannot return the current Promise object:

let p1 = p.then(data= >{
  console.log(data)
  return p1
})
Copy the code

Then returns the same Promise as the current Promise object

class MyPromise{... then =(successCallback,failCallback) = >{
    let p2 = new MyPromise((resolve,reject) = >{
      if(this.status === FULFILLED){
        setTimeout(() = >{
          let x = successCallback(this.successParams);
          promiseResolve(p2,x,resolve,reject)
        },0); }... })returnp2; }}function promiseResolve(p,x,resolve,reject){
  if(p === x){
    return reject(new TypeError('error'))}... }Copy the code

1. SetTimeout must be added, otherwise the current Promise object p2 and then return the current Promise object; 2. When used, it is not possible to call the link then, so that the two promises are different and cannot be compared, as shown below

Incorrect: P.teng (p.teng)data= >{
  console.log(data)
  return p1
}).then(data1= >{
  console.log(111)},reason= >{
  console.log(reason)}let p1 = p.then(data= >{
  console.log(data)
  return p1
})
p1.then(data1= >{
  console.log(111)},reason= >{
  console.log(reason)
})
Copy the code

Catch errors in promises

Idea: The source of the error in promise

  • The Promise executes the function immediately
  • Two functions in then
class MyPromise{
  constructor(execute){
    try {
      execute(this.resolve,this.reject)
    } catch (error) {
      this.reject(error)
    }
  }
  ...
  resolve = (value) = >{...while(this.successCallback.length) this.successCallback.shift()()
  }
  reject = (error) = >{...while(this.failCallback.length) this.failCallback.shift()()
  }
  then = (successCallback,failCallback) = >{
    let p2 = new MyPromise((resolve,reject) = >{
      if(this.status === FULFILLED){
        setTimeout(() = >{
          try {
            let x = successCallback(this.successParams);
            promiseResolve(p2,x,resolve,reject)
          } catch (error) {
            reject(error)
          }
        },0);
      }
      if(this.status === REJECTED){
        setTimeout(() = >{
          try {
            let x = failCallback(this.failParams);
            promiseResolve(p2,x,resolve,reject)
          } catch (error) {
            reject(error)
          }
        },0);
      }
      if(this.status === PENDING){
        this.successCallback.push(() = >{
          setTimeout(() = >{
            try {
              let x = successCallback(this.successParams);
              promiseResolve(p2,x,resolve,reject)
            } catch (error) {
              reject(error)
            }
          },0);
        });
        this.failCallback.push(() = >{
          setTimeout(() = >{
            try {
              let x = failCallback(this.failParams);
              promiseResolve(p2,x,resolve,reject)
            } catch (error) {
              reject(error)
            }
          },0); }); }})returnp2; }}Copy the code

Note that asynchronous methods execute only after resolve/reject before the next corresponding THEN function,

Promise also has a method to call. Then is empty

p.then().then().then(value= >console.log(value))
Copy the code

When there is no function in then, complete the function.

const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';
class MyPromise{
  constructor(execute){
    try {
      execute(this.resolve,this.reject)
    } catch (error) {
      this.reject(error)
    }
  }
  status = PENDING;
  successParams = undefined;
  failParams = undefined;
  successCallback = [];
  failCallback = [];
  resolve = (value) = >{
    if(this.status ! == PENDING)return;
    this.status = FULFILLED;
    this.successParams = value;
    while(this.successCallback.length) this.successCallback.shift()()
  }
  reject = (error) = >{
    if(this.status ! == PENDING)return;
    this.status = REJECTED;
    this.failParams = error;
    while(this.failCallback.length) this.failCallback.shift()()
  }
  then = (successCallback,failCallback) = >{
    successCallback = successCallback ? successCallback : value= > value;
    failCallback = failCallback ? failCallback : value= > value;
    let p2 = new MyPromise((resolve,reject) = >{
      if(this.status === FULFILLED){
        setTimeout(() = >{
          try {
            let x = successCallback(this.successParams);
            promiseResolve(p2,x,resolve,reject)
          } catch (error) {
            reject(error)
          }
        },0);
      }
      if(this.status === REJECTED){
        setTimeout(() = >{
          try {
            let x = failCallback(this.failParams);
            promiseResolve(p2,x,resolve,reject)
          } catch (error) {
            reject(error)
          }
        },0);
      }
      if(this.status === PENDING){
        this.successCallback.push(() = >{
          setTimeout(() = >{
            try {
              let x = successCallback(this.successParams);
              promiseResolve(p2,x,resolve,reject)
            } catch (error) {
              reject(error)
            }
          },0);
        });
        this.failCallback.push(() = >{
          setTimeout(() = >{
            try {
              let x = failCallback(this.failParams);
              promiseResolve(p2,x,resolve,reject)
            } catch (error) {
              reject(error)
            }
          },0); }); }})returnp2; }}function promiseResolve(p,x,resolve,reject){
  if(p === x){
    return reject(new TypeError('error'))}if(x instanceof MyPromise){
    x.then(resolve,reject)
  }else{
    resolve(x)
  }
}
Copy the code

If there is any mistake or not precise place, please be sure to give correction, thank you very much.