When multiple operations are required, multiple callback functions can be nested, resulting in unintuitive code known as callback hell, which is usually solved with promises

I’ll make a Promise to you after a certain amount of time. When is it used over a period of time? The answer is asynchronous operations, which are things that take a long time to produce results, such as network requests, reading local files, etc

Constructor initializes the logic

const PENDING =  'pending'; // this is a big pity'fulfilled'; // Const REJECTED ='rejected'; / / the initial stateletself = this; // Cache the current promise instance self.status = PENDING; // Set the state self.onresolvedCallbacks = []; Self.onrejectedcallbacks = []; // Define an array of failed callbacksCopy the code

An executor executor that takes resolve and reject. The new Promise executor will execute

Promise has three states: the initial state is “pending”, the success state is “depressing”, and the failure state is “Rejected”. If the code succeeds, it will not fail. If it is always pending, it will never give you a definite answer

If a promise is in a pending state, it can be converted to a successful state. If a promise is already in a successful or failed state, it does nothing

  function resolve(value){ 
    if(value! =null &&value.then&&typeof value.then =='function') {return value.then(resolve,reject);
    }
    setTimeout(function() {if(self.status == PENDING){ self.status = FULFILLED; self.value = value; self.onResolvedCallbacks.forEach(cb=>cb(self.value)); }})}functionReject (reason) {/ / 2.1.2setTimeout(function() {if(self.status == PENDING){ self.status = REJECTED; self.value = reason; self.onRejectedCallbacks.forEach(cb=>cb(self.value)); }}); }}Copy the code

Because this function can execute in an exception, you need to catch it. If something goes wrong, reject the error object. If it fails, reject the promise, the cause of the failure, and try… catch(e)… For processing

  try{
    executor(resolve,reject);
  }catch(e){
    reject(e);
  };
Copy the code

The resolution process for promises

function resolvePromise(promise2,x,resolve,reject){
  if(promise2 === x){
    return reject(new TypeError('Circular reference'));
  }
  let called = false;
  if(x instanceof Promise){
    if(x.status == PENDING){
      x.then(function(y){
        resolvePromise(promise2,y,resolve,reject);
      },reject);
    }else{ x.then(resolve,reject); }}else if(x! = null &&((typeof x=='object')||(typeof x == 'function'))){
   try{
     let then = x.then;
     if(typeof then= ='function'){
       then.call(x,function(y){
          if(called)return;
          called = true;
          resolvePromise(promise2,y,resolve,reject)
       },function(err){
         if(called)return;
         called = true;
         reject(err);
       });
     }else{
       resolve(x);
     }
   }catch(e){
     if(called)return;
     called = true; reject(e); }}else{ resolve(x); }}Copy the code

The then method is used to specify the actions to be performed when the state of the Promise object changes. The first function (ondepressing) is performed in the resolve method, and the second function (onRejected) is performed in the reject method. In this method, if the successful and failed callbacks are not passed, Then means that the then has no logic and only throws the value backwards

Promise.prototype.then = function(onFulfilled,onRejected){
  onFulfilled = typeof onFulfilled == 'function'? onFulfilled:function(value){return  value};
  onRejected = typeof onRejected == 'function'? onRejected:reason=>{throw reason};let self = this;
  let promise2;
  if(self.status == FULFILLED){
    return promise2 = new Promise(function(resolve,reject){
      setTimeout(function(){
        try{
          letx =onFulfilled(self.value); resolvePromise(promise2,x,resolve,reject); }catch(e){ reject(e); }})}); }if(self.status == REJECTED){
    return promise2 = new Promise(function(resolve,reject){
      setTimeout(function(){
        try{
          letx =onRejected(self.value); resolvePromise(promise2,x,resolve,reject); }catch(e){ reject(e); }})}); }if(self.status == PENDING){
   return promise2 = new Promise(function(resolve,reject){
     self.onResolvedCallbacks.push(function(){
         try{
           letx =onFulfilled(self.value); resolvePromise(promise2,x,resolve,reject); }catch(e){ reject(e); }}); self.onRejectedCallbacks.push(function(){
         try{
           letx =onRejected(self.value); resolvePromise(promise2,x,resolve,reject); }catch(e){ reject(e); }}); }); }}Copy the code

The chain call to promise

  • Each call returns a new Promise instance
  • Arguments to chained calls are passed by return value: that is, the first then succeeds and its return value is taken as an argument to the next successful callback
  • thenThe reason you can write a chained call is that it always returns one every time the method is executedPromiseobject

Then (undefined, onRejected); This is just an alias for the method. That is, this method is used to register the callback function catch when the State of the Promise object changes to Rejected

Promise.prototype.catch = function(onRejected){
  this.then(null,onRejected);
}
Copy the code

Promise.all takes an array of Promise objects as arguments, and calls the.then method when all the Promise objects in the array are resolved or reject

Promise.all = function(promises){
 return new Promise(function(resolve,reject){
   let done = gen(promises.length,resolve);
   for(leti=0; i<promises.length; i++){ promises[i].then(function(data){
       done(i,data); },reject); }}); }Copy the code

As long as one of the Promise objects enters the FulFilled or Rejected state, the following processing will be continued

Promise.race = function(promises){
  return new Promise(function(resolve,reject){
    for(leti=0; i<promises.length; i++){ promises[i].then(resolve,reject); }}); }Copy the code

If you’re given a method that requires you to pass in a promise, but you only have a generic value, you can use this method to turn that generic value (string Number object) into a Promise object that returns an immediate promise

Promise.resolve = function(value){
  return new Promise(function(resolve){
    resolve(value);
  });
}
Copy the code

Return a promise that fails immediately

Promise.reject = function(reason){
  return new Promise(function(resolve,reject){
    reject(reason);
  });
}
Copy the code