손 으로 쓴 Promise - 자신 이 Promise 대상 을 봉인 합 니 다.

34599 단어 JavaScript
스스로 Promise 를 봉인 하 다
코드:https://github.com/fu-x/promise 우선 Promise 에 대한 분석 이 필요 합 니 다.
MyPromise 클래스 설명
class MyPromise {} //   MyPromise 

Promise 의 세 가지 상태: pending, fulfilled, rejected
우 리 는 클래스 에서 세 개의 정적 상수 를 정의 해 야 한다.
static PENDING = 'pending'; // pending         
static FULFILLED = 'fulfilled'; // fulfilled        
static REJECTED = 'rejected'; // rejected        

Promise 기본 방법 (constructor)
  • 함 수 를 받 아들 여 실행 해 야 합 니 다. 함 수 는 내부 resolved 와 rejected 방법
  • 을 호출 해 야 합 니 다.
  • 비동기 함 수 를 저장 하 는 개인 속성 을 정의 해 야 합 니 다
  • 현재 상 태 를 저장 하 는 개인 속성 을 정의 해 야 합 니 다
  • constructor(executor) { //     ,      。
      this.status = MyPromise.PENDING; //       
      this.value = null;
      this.callbacks = []; //   pending      
      try { //     
        executor(this.resolved.bind(this), this.rejected.bind(this)); //     
      } catch (error) {
        this.rejected(error) //    rejected  
      }
    }
    

    resolved 방법: 성공 적 인 비동기 함수 실행
    resolved(value) { //        
      if (this.status === MyPromise.PENDING) { //     ,   pending  
        this.status = MyPromise.FULFILLED; //      fulfilled
        this.value = value;
        this.callbacks.forEach(callback => { //       ,  pending             
          callback.onFulfilled(this.value);
        })
      }
    }
    

    rejected 방법: 실행 실패 한 비동기 함수
    rejected(error) { //        
      if (this.status === MyPromise.PENDING) { //     ,   pending  
        this.status = MyPromise.REJECTED; //      rejected
        this.value = error;
        this.callbacks.forEach(callback => { //       ,  pending             
          callback.onRejected(this.value);
        })
      }
    }
    

    promise 의 개인 적 인 방법: then
  • 두 개의 반전 함수 인 자 를 받 아들 여야 합 니 다. onFulfilled, onRejected
  • 세 가지 상 태 를 각각 처리 해 야 한다
  • 매개 변 수 는 비어 있 고 상 태 를 바 꾸 지 않 습 니 다
  • 리 셋 함수 에서 Promise 대상 을 되 돌려 줍 니 다
  • then Promise 대상 으로 돌아 가 야 합 니 다
  • 체인 호출 실현 가능
  • 현재 Promise 상 태 는 다음 Promise 상태 에 영향 을 주지 않 습 니 다
  • then 의 비동기 조작 실현 (setTimeout)
  • 이상 검 측, 코드 이상 은 rejected 상태 로 처리
  • //   then()  。 onFulfilled onRejected               
    then(onFulfilled, onRejected) {
      //                ,       ,  then     
      onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : () => this.value;
      onRejected = typeof onRejected === 'function' ? onRejected : () => this.value;
      //     ,then     MyPromise
      let myPromise2 = new MyPromise((resolve, reject) => {
        //        pending,             。
        if (this.status === MyPromise.PENDING) {
          this.callbacks.push({
            onFulfilled: value => {
              setTimeout(() => {    //   then     
                let result = onFulfilled(value);
                if(result === myPromise2){  //            ,             promise  
                  throw new TypeError('Chaining cycle detected');
                }
                try {     //     
                  if(result instanceof MyPromise){  //              promise  
                    result.then(resolve, reject);  //   .then            
                  }else{
                  resolve(result);   //   then   promise,  resolve,      then
                  }
                } catch (error) {
                  reject(error);
                }
              })
            },
            onRejected: value => {
              setTimeout(() => { //   then     
                let result = onRejected(value);
                if(result === myPromise2){  //            ,             promise  
                  throw new TypeError('Chaining cycle detected');
                }
                try { //     
                  if(result instanceof MyPromise){  //              promise  
                    result.then(resolve, reject);  //   .then            
                  }else{
                    resolve(result);   //   then   promise,  resolve,      then
                  }
                } catch (error) {
                  reject(error);
                }
              })
            }
          })
        //     ,      
        } else if (this.status === MyPromise.FULFILLED) {
            setTimeout(() => { //   then     
            let result = onFulfilled(this.value);
            if(result === myPromise2){  //            ,             promise  
              throw new TypeError('Chaining cycle detected');
            }
            try { //     
              if(result instanceof MyPromise){  //              promise  
                result.then(resolve, reject);  //   .then            
              }else{
                resolve(result);   //   then   promise,  resolve,      then
              }
            } catch (error) {
              reject(error);
            }
          })
        //     ,      
        } else if (this.status === MyPromise.REJECTED) {
          setTimeout(() => { //   then     
            let result = onRejected(this.value);
            if(result === myPromise2){  //            ,             promise  
              throw new TypeError('Chaining cycle detected');
            }
            try { //     
              if(result instanceof MyPromise){  //              promise  
                result.then(resolve, reject);  //   .then            
              }else{
                resolve(result);   //   then   promise,  resolve,      then
              }
            } catch (error) {
              reject(this.value);
            }
          })
        }
      })
      return myPromise2;
    }
    

    promise 의 정적 방법: resolve
  • Promise 대상 을 되 돌려 줍 니 다
  • 하나의 Promise 대상 을 매개 변수 로 받 아들 일 수 있다
  • 파라미터 가 Promise 대상 이면 되 돌아 오 는 Promise 상태 가 파라미터 인 Promise 상태
  • 인자 가 Promise 대상 이 아니라면 되 돌아 오 는 Promise 상태 가 성공
  • //   promise    resolve
    static resolve(value){  
      return new MyPromise((resolve, reject)=>{   // resolve    promise  
        if(value instanceof MyPromise){   //            promise  
          value.then(resolve, reject);  //   then  ,    promise  
        }else{
          resolve(value);   //     promise  ,     
        }
      })
    }
    

    promise 의 정적 방법: reject
  • Promise 대상 을 되 돌려 줍 니 다
  • 되 돌아 오 는 Promise 상 태 는 실패
  •  //   promise    reject
     static reject(value){  
       return new MyPromise((resolve, reject)=>{   // reject    promise  
         reject(value);    //      
       })
     }
    

    promise 의 정적 방법: all
  • Promise 대상 을 되 돌려 줍 니 다
  • 하나의 배열 을 받 아들 이 고 배열 요 소 는 Promise 대상
  • 이다.
  • 배열 의 모든 promise 요소 상태 가 성공 하면 promise 상 태 를 성공 으로 되 돌려 줍 니 다. 그렇지 않 으 면 실패
  • //   promise    all,    promise  ,    promise  
    //       promise       ,   promise     ,     
    static all(promises){ 
      return new MyPromise((resolve, reject)=>{
        const values = [];
        promises.forEach(promise=>{
          promise.then((data)=>{
            values.push(data);
            if(values.length === promises.length){
              resolve(data);
            }
          }, (error)=>{
            reject(error);
          })
        })
      })
    }
    

    promise 의 정적 방법: race
  • Promise 대상 을 되 돌려 줍 니 다
  • 하나의 배열 을 받 아들 이 고 배열 요 소 는 Promise 대상
  • 이다.
  • 하나의 promise 상 태 를 배열 에서 가장 빠 른 promise 상태 로 되 돌려 줍 니 다
  • //   promise    race,    promise  
    //     promise           promise  
    static race(promises){
      return new MyPromise((resolve, reject)=>{
        promises.forEach(promise=>{
          promise.then(data=>{
            resolve(data);
          }, error=>{
            reject(error);
          })
        })
      })
    }
    

    여기 서 우리 Promise 는 패키지 가 완성 되 었 습 니 다. 복잡 해 보이 지만 모든 방법 과 속성의 역할 을 알 면 그 논리 가 간단 하 다 는 것 을 알 수 있 습 니 다.

    좋은 웹페이지 즐겨찾기