프로미스

4464 단어 es6
promise 인스턴스:
var getJSON = function(url) {
    var promise = new Promise(function(resolve, reject) {
        // XHR ajax 
        var client = new XMLHttpReqeust();
        client.open("GET", url);
        client.onreadystatechange = handler;
        client.responseType = "json";
        client.setRequestHeader("Accept", "application/json");
        client.send();
         
        function hanlder(){
            if (this.readyState !== 4) {
                return;
            }
            if (this.status === 200) {
                resolve(this.response);
            } else {
                reject(new Error(this.statusText));
            }
        };
    });
    return promise;
}
getJSON("/posts.json").then(function(json) {
    console.log("Content: " + json);
}, function(error) {
    console.error(" !', error);
});

위에서 설명한 바와 같이 new Promise를 호출할 때 함수function(resolve,reject)을 전달했는데 이 함수는 규범에서 exector 집행기라고 부른다.따라서 우선: exector 실행기에 전송해야 합니다.
function Promise(exector) {
    //...
}

Promise 내부 exector의 역할을 확인합니다: 원생 exector에 2개의 매개 변수, resolve와reject가 전송되었음을 알 수 있습니다.첫 번째는 성공을 대표하고, 두 번째는 실패를 대표한다.
function Promise(exector) {
    let self = this;
    this.value = undefined;
    this.reason = reason;
    
    //  
    function resolve(value) {
        self.value = value;
    }
    
    //  
    function reject(reason) {
        self.reason = reason;
    }
     
    exector(resolve, reject);
}

상태 추가:promise의 실행 과정은 거스를 수 없습니다. 따라서 상태를 기록하려면 status가 필요합니다. 처음에는padding이고,resolve가 성공했고,reject가 실패했습니다.
function Promise(exector) {
    let self = this;
    this.status = "padding";
    this.value = value;
    this.reason = reason;
   
    //  
    function resolve(value) {
        if(self.status === "padding") {
            self.value = value;
            self.status = "resolved";
        }
    }
     
    //  
    function  reject(reason) {
        if(self.status === "padding") {
            self.reason = reason;
            self.status = "reject";
        }
    }
   
    //  
    try {
        exector(resolve, reject);
    } catch(e) {
        reject(e)
    }
}

원형에 then 방법을 추가합니다:Promise 실례의 사용은 p.then(onFulfilled,onRejected)이므로 앞에서 정의한 Promise의 원형에 then 방법을 추가할 수 있습니다.
Promise.prototype.then = function(onFulfilled, onRejected) {
    let self = this;
    if(this.status === "resolved") {
        onFulfilled(self.value);
    }
     
    if(this.status === "rejected") {
        onRejected(self.value);
    }
}

두 개의 그룹을 추가하여 비동기 동작을 완성합니다. 위에서 작성한 Promise의 호출은 동기화되지만, 일반적으로 비동기적으로 Promise를 사용하기 때문에 Promise와 그 원형에 대해 일정한 수정을 해야 합니다.비동기적이면padding 상태입니다. 리셋 함수 fn을 그룹에 저장합니다!
function Promise(exector) {
    let self = this;
    this.status = "padding";
    this.value = undefined;
    this.reason = undefined;
    
    //  then 
    this.onResolvedCallbacks = [];
    //  then 
    this.onRejectedCallbacks = [];
   
   //  
   function resolve(value) {
       if(self.status === "padding") {
           self.value = value;
           self.status = "resolved";
            
           //  then 
           self.onResolvedCallbacks.forEach(fn => fn());
       }
   }
    
   //  
   function reject(reason) {
       if(self.status === "padding") {
           self.reason = reason;
           self.status = "rejected";
            
           //  then 
           self.onRejectedCallbacks.forEach(fn => fn());
       }
   }
    
   //  
   try {
       exector(resolve, reject);
   } catch(e) {
       reject(e)
   }
}

// Promise.prototype.then
Promise.prototype.then = function(onFulfilled, onRejected) {
    let self = this;
    
    //  
    if (this.status === "resolved") {
        onFulfilled(self.value);
    }
    //  
    if (this.status === "rejected") {
        onRejected(self.reason);
    }
    // padding
    if (this.status === "padding") {
        //  onResolvedCallbacks 
        this.onResolvedCallbacks.push( () => {
            onFulfilled(self.value);
        })
        this.onRejectedCallbacks.push( () => {
            onRejected(self.reason);
        })
    }
}

ES6 Standard Enterprise(버전 3) 참조 P276 참조https://www.jianshu.com/p/4b126518c26d

좋은 웹페이지 즐겨찾기