Promise 가 뭐야?하나의 Promise 를 실현 하 다.

11898 단어
1. 왜 promise 가 생 겼 을 까?
  • 여러분 들 이 JS 를 쓸 때 리 셋 함 수 를 썼 다 고 믿 습 니 다. 다 층 리 셋 을 썼 을 때 논 리 는 이미 명확 하 게 정리 하기 어 려 웠 습 니 다. 이것 이 바로 promise 가 해결 한 문제 입 니 다. 리 셋 지옥
  • 다 중 포 함 된 리 턴 에 동기 / 비동기 적 인 방법 이 있 으 면 실행 순서 가 혼 란 스 럽 고 promise 는 체인 호출 을 사용 합 니 다.

  • 2. promise 란 무엇 인가?
  • 이른바 promise 는 중국어 로 '약속, 약속' 이 라 고 번역 합 니 다. 예 를 들 어 이번 달 에 돈 을 벌 어서 아내 에 게 가방 을 사 주 겠 다 고 약속 하면 먼저 돈 을 벌 고 돈 을 벌 면 바로 아내 에 게 가방 을 사 주 겠 다 고 약속 하고 돈 을 벌 지 못 하면 바로 사과 하 세 요.코드 로 바 꾸 면:
          //      
          const geilaopomaibao = new Promise((resolve, reject) => {
              //      
              if (money) {
                  //    
                  reslove('10k');
              } else {
                  //     
                  reject('      ,       ');
              }
          })
          
          //        ,        。
          geilaopomaibao.then(
              res => {
                  // res      
                  maibao(res);
              },
              reason => {
                  //   
                  // reason     
              }
          );
    
  • promise 는 일종 의 규범 이다. 즉, 모두 가 자신의 promise 를 실현 할 수 있 고 규범 을 따 르 기만 하면 된다.ES6 에서 도 promise 를 정식으로 도입 했다. 물론 promise 규범 을 실현 하 는 라 이브 러 리 도 많다. 예 를 들 어 Q, bluebird 규범: Promises / A + Promises / A + 중국어
  • 3. promise 를 어떻게 사용 합 니까?
    -          : 
    ``` const task = new Promise((resolve, reject) => { setTimeout(() => { resolve(' '); }, 3000); }) task.then((res) => { // 3 console.log(res); }) ``` , callback resolve, ``` // , ,then new Promise((resolve, reject) => { $.ajax('/api/user/login', { success: function(isLogin) { if (isLogin) { resolve(data); } else { reject(' '); } } }) }).then( res => { $.ajax('/api/list', { success: function(data) { resolve(data); } }) }, reason => { alert(reason) } ).then((data) => { // data list // list return data.sort(); }).then((list) => { // , list }) ``` - promise , ; 1. Promise.all() ( promise , , ) ``` const task1 = {ji: 2018}; const task2 = new Promise((resolve, reject) => { setTimeout(() => { resolve('2018 '); }, 5000); }); const task3 = new Promise((resolve, reject) => { setTimeout(() => { resolve(' '); }, 2000); }); Promise.all([task1, task2, task3]).then(values => { console.log(values); // 5 [{ji: 2018}, '2018 ', ' '] }); ``` 2. Promise.race() ( promise , , promise ) ``` const task2 = new Promise((resolve, reject) => { setTimeout(() => { resolve('2018 '); }, 5000); }); ; const task3 = new Promise((resolve, reject) => { setTimeout(() => { resolve(' '); }, 2000); }); Promise.race([task1, task2, task3]).then(values => { console.log(values); // 2 ' ' }); ``` 3. Promise.resolve() ( , promise, : promise, , ) ``` /** * @param {Promise} fn promise */ const task = (fn) => { fn.then() // ........ } Promise.resolve(1); ``` 4. Promise. reject() ( , promise)

    4. 하나의 promise 실현
    class Promise {
        constructor(task) {
    
            //         { pending fulfilled rejected } 3   
            this.status = 'pending';
    
            //  resolve    
            this.resolveData = null;
    
            //  reject    
            this.rejectData = null;
    
            //              
            this.onFulfilledList = [];
            this.onRejectedList = [];
    
            //       
            try {
                task(this.onResolve.bind(this), this.onReject.bind(this));
            } catch (e) {
                this.onReject(e);
            }
        }
    
        /**
         *   ,  
         * 
         * @param {any} data resolve  
         */
        onResolve(data) {
            if (this.status === 'pending') {
                this.status = 'fulfilled';
                this.resolveData = data;
                this.onFulfilledList.forEach(fn => {
                    fn(this.resolveData);
                })
            }
        }
    
        /**
         *   ,  
         * 
         * @param {any} data reject  
         */
        onReject(data) {
            if (this.status === 'pending') {
                this.status = 'rejected';
                this.rejectData = data;
                this.onRejectedList.forEach(fn => {
                    fn(this.rejectData);
                })
            }
        }
    
        /**
         *   
         *
         * @param {function} onFulfilled     
         * @param {function} onRejected     
         * @return {*}
         */
        then(onFulfilled, onRejected) {
            if (typeof onFulfilled !== 'function') {
                onFulfilled = () => {};
            }
    
            if (typeof onRejected !== 'function') {
                onRejected = () => {};
            }
    
            let promise2;
    
            switch (this.status) {
                case 'pending':
                    promise2 = new Promise((resolve,reject) => {
                        this.onFulfilledList.push(() => {
                            let x = onFulfilled(this.resolveData);
                            this.resolvePromise(promise2, x, resolve, reject);
                        });
                        this.onRejectedList.push(() => {
                            let x = onRejected(this.rejectData);
                            this.resolvePromise(promise2, x, resolve, reject);
                        });
                    });
                    break;
                case 'fulfilled':
                    promise2 = new Promise((resolve, reject) => {
                        let x = onFulfilled(this.resolveData);
                        this.resolvePromise(promise2, x, resolve, reject);
                    });
                    break;
                case 'rejected':
                    promise2 = new Promise((resolve, reject) => {
                        let x = onRejected(this.rejectData);
                        this.resolvePromise(promise2, x, resolve, reject);
                    });
                    break;
                default:
                    throw 'promise status error';
            }
    
            return promise2;
        }
    
        /**
         * catch      reject
         *
         * @param onRejected
         */
        catch(onRejected) {
            if (typeof onRejected !== 'function') {
                onRejected = () => {};
            }
    
            let promise2;
    
            promise2 = new Promise((resolve, reject) => {
                let x = onRejected(this.rejectData);
                this.resolvePromise(promise2, x, resolve, reject);
            });
        }
    
        /**
         *     ,  then
         *
         * @param {Promise} promise2    promise
         * @param {any} x    then      
         * @param {function} resolve        
         * @param {function} reject        
         * @return {*}
         */
        resolvePromise(promise2, x, resolve, reject) {
            //    then  
            let then;
            //   x    promise2     
            if(promise2 === x){
                return reject(new TypeError('    '));
            }
    
            if (x instanceof Promise) {
                if(x.status === 'pending'){
                    x.then(function(y){
                        resolvePromise(promise2, y, resolve, reject);
                    }, reject);
                } else if (x.status === 'fulfilled'){
                    resolve(x.resolveData);
                } else if (x.status === 'rejected'){
                    reject(x.rejectData);
                }
            } else if (x != null && (typeof x === 'object' || typeof x === 'function')) {
                try {
                    //      then  
                    then = x.then;
                    //   then fn     then  
                    if (typeof then == 'function') {
                        then.call(x, function (y) {
                            resolvePromise(promise2, y, resolve, reject)
                        }, reject);
                    } else {
                        //   then   fn   x  fulfill promise
                        resolve(x);
                    }
                } catch (e) {
                    reject(e);
                };
            } else {
                resolve(x);
            }
        }
    
        /**
         * all       ,    promise  
         * 1.       reject,   reject
         *
         * @param {Array} promiseList        
         * @return {Promise}
         */
        static all(promiseList) {
            //         ,    
            if (!Array.isArray(promiseList)) {
                new TypeError('must be an array');
            }
            return new Promise((resolve, reject) => {
                //          0    resolve
                if (promiseList.length === 0) {
                    resolve([]);
                }
    
                const allData = new Array();
    
                let resI = 0;
    
                promiseList.forEach((item, index) => {
                    if (item instanceof Promise) {
                        item.then(
                            res => {
                                allData[index] = res;
                                resolveAll();
                            },
                            rej => {
                                reject(rej);
                            }
                        )
                    } else {
                        allData[index] = item;
                        resolveAll();
                    }
                })
    
                function resolveAll() {
                    resI++;
    
                    if (resI === promiseList.length) {
                        resolve(allData);
                    }
                }
            });
        }
    
        /**
         * race        promise  ,   
         *
         * @param {Array} promiseList        
         * @return {Promise}
         */
        static race(promiseList) {
            //         ,    
            if (!Array.isArray(promiseList)) {
                new TypeError('must be an array');
            }
    
            return new Promise((resolve, reject) => {
                //          0    resolve
                if (promiseList.length === 0) {
                    resolve([]);
                }
    
                promiseList.forEach(item => {
                    promiseList.forEach(item => {
                        if (item instanceof Promise) {
                            item.then(
                                res => {
                                    resolve(res);
                                },
                                rej => {
                                    reject(rej);
                                }
                            )
                        } else {
                            resolve(item);
                        }
                    })
                })
            })
        }
    
        /**
         * resolve  
         *
         * @param value
         * @return {Promise}
         */
        static resolve(value) {
            return new Promise((resolve, reject) => {
                if (value instanceof Promise) {
                    value.then(res => {
                        resolve(res);
                    })
                } else {
                    resolve(value);
                }
            })
        }
    
        /**
         * reject  
         *
         * @param reason
         * @return {Promise}
         */
        static reject(reason) {
            return new Promise((resolve, reject) => {
                reject(reason);
            })
        }
    }
    

    좋은 웹페이지 즐겨찾기