Promiseの分析とシミュレーションの実現


1.Promiseを知る
周知のように、PromiseはJSにおいて非同期的にプログラムされた解決策である.シミュレーションがPromiseを実現する前に、まずPromiseの特性を知る必要があります.
1.promise(Promiseの例)は、3つの状態があり、初期時の待ち状態がpendingであり、成功時の成功状態がreolved及び失敗状態reject edである.promiseの状態は一回だけ変えられます.pendingからreolvedまたはrejectdになるしかないです.不可逆を変えます.2.promiseが状態を変える方式は三つあります.reolveを呼び出した時に、pendingからreolvedになり、rejectを呼び出したり、アクチュエータ関数の内部に異常が投げられたら、pendingからrejectになります.3.同じプロミセに対して複数のコールバック関数を指定した場合、プロミセが対応状態になった場合、対応するコールバック関数は全部実行されます.4.p.then()が戻ってきたPromiseの結果の状態はどうなりますか?thenによって指定されたコールバック関数の結果は、①異常を投げたら、新しいpromiseがreject②コールバック関数が戻ってくるのがPromiseの任意の値string、undefinedなどであれば、新しいpromiseがfulfilledになり、データは戻り値③コールバック関数が返ってくるのがpromiseオブジェクトです.リターン値プロミスオブジェクトの結果と状態は新しいプロミスの結果と状態5.promise異常透過です.前のthenに成功したコールのみを書いています.失敗したコールは暗黙的に書きました.最後に指定された失敗のコールバック②前の任意の操作で異常が発生したら最後の失敗のコールバック関数に処理することができます.プロミセチェーンを中断します.プロミセチェーンを使って呼び出した場合、途中で中断します.後のコールバック関数を呼ばない方法:必要であれば、必要であれば、一つのpending状態のプロミセリセットnew Promise()={)
2.Promiseのシミュレーション実現
Promiseにおけるthen、catch、all、race、reolve、rejectを実現します.使う時はES 6文法です.
1.MyPromise全体構成
class MyPromise {
    //             
    constructor(executor) {
       
    }
    //            ,      promise
    then(resolvedCallBack, rejectedCallBack = error => { throw error }) {
    }
    //      promise
    catch(rejectedCallBack) {
    }
    /**
     * @author: forceddd
     * @desc:              promise  
     * @param ArrayOfPromises
     * @return:        promise                
     */
    static race(promises) {
    }
    /**
     * @author: forceddd
     * @desc:    promise    ,        promise      promise                    promise
     * @param ArrayOfPromises
     * @return: promise
     */
    static all(promises) {
       
    }
    /**
     * @author: forceddd
     * @desc:    promise         promise data    
     *   promise             promise        
     * @param any 
     * @return:          promise
     */

    static resolve(data) {

    }
    /**
     * @author: forceddd
     * @desc:      promise
     * @param reason 
     * @return:          promise            
     */
    static reject(error) {
    }

}
2.コンストラクタの実現
//             (           )
    constructor(executor) {
        this.status = 'pending';//       
        this.data = undefined;//          
        this.callBacks = [];//    promise    ,     pending ,          [{resolveCb,rejectCb}] 
        //     this        this       resolve reject  this   window
        //        promise     ,              executor 
        const resolve = data => {
            //status                  pending
            if (this.status !== 'pending') return;

            //  promise      
            this.status = 'resolved';
            //     
            this.data = data;

            //                     --   --        
            //  setTimeout              
            if (this.callBacks.length) {
                setTimeout(() => {
                    this.callBacks.forEach(cbObj => cbObj.resolvedCallBack(data))
                })
            }
        }
        const reject = error => {
            //status                  pending
            if (this.status !== 'pending') return;

            //  promise      
            this.status = 'rejected';
            //      
            this.data = error;
            //                     --  --        
            //  setTimeout              
            if (this.callBacks.length) {
                setTimeout(() => {
                    this.callBacks.forEach(cbObj => cbObj.rejectedCallBack(error))
                })
            }
        }
        //     executor try catch    executor     
        try {
            executor(resolve, reject)
        } catch (error) {
            //       ,promise   rejected
            reject(error)
        }
    }
3.thenの実現
//            ,      promise
    // rejectedCallBack                 rejectedCallBack,
    //       ,       ,    , then   promise     
    then(resolvedCallBack, rejectedCallBack = error => { throw error }) {
        //   catch  resolvedCallBack      null             
        resolvedCallBack = typeof resolvedCallBack === 'function' ? resolvedCallBack : _ => _;
        //then       promise
        return new MyPromise((resolve, reject) => {
            /**
             * @desc:   then     
             *  1.                      promise error     
                2.           promise   ,       promise data        
                3.             promise    promise           promise                       
             * @param: cb
             * @return: 
             */
            const handleReturn = cb => {
                let res;//                 
                try {
                    res = cb(this.data);
                    res instanceof MyPromise
                        //3.             promise    promise           promise      
                        ? res.then(
                            data => resolve(data),
                            error => reject(error)
                        )
                        //          resolve      resolvedCallBack         resolvedCallBack(this.data),
                        //     data => resolve(data)    
                        // res.then(resolve, reject)
                        //2.           promise   ,       promise data        
                        : resolve(res)
                } catch (error) {
                    //1.                      promise error      
                    reject(error)
                }
            }
            if (this.status === 'pending') {
                //       pending                        callBacks 
                //                 then                      ,        ,          
                // this.callBacks.push({ resolvedCallBack, rejectedCallBack })
                this.callBacks.push({
                    resolvedCallBack: _ => handleReturn(resolvedCallBack),
                    rejectedCallBack: _ => handleReturn(rejectedCallBack)
                })
                /*                    --  --   */
            } else if (this.status === 'resolved') {
                setTimeout(() => handleReturn(resolvedCallBack));
            } else {
                setTimeout(() => handleReturn(rejectedCallBack));
            }
        })
    }
4.catchの実現
    //      promise catch then      
    catch(rejectedCallBack) {
        return this.then(null, rejectedCallBack)
    }
5.reolveとrejectの実現
/**
     * @author: forceddd
     * @desc:    promise         promise data    
     *   promise             promise        
     * @param any 
     * @return:          promise
     */
static resolve(data) {

        return new MyPromise((resolve, reject) => {
            data instanceof MyPromise
                ? 
                /*res.then(
                       data => resolve(data),
                       error => reject(error)
                        )
                           */
                data.then(resolve, reject)
                : resolve(data)
        })
    }
    /**
     * @author: forceddd
     * @desc:      promise
     * @param reason 
     * @return:          promise            
     */
    static reject(error) {
        return new MyPromise((_, reject) => reject(error))
    }
6.raceの実現
/**
     * @author: forceddd
     * @desc:              promise  
     * @param ArrayOfPromises
     * @return:        promise             
     */
    static race(promises) {
        //    promise
        return new MyPromise((resolve, reject) => {
            promises.forEach(promise => {
                //       promise     ,  resolve     promise
                promise = promise instanceof MyPromise ? promise : MyPromise.resolve(promise);
                //      promise        race          
                promise.then(resolve, reject)
            })
        })
    }
7.allの実現
 /**
     * @author: forceddd
     * @desc:    promise    ,        promise      promise                    promise
     * @param ArrayOfPromises
     * @return: promise
     */
    static all(promises) {
        let resolveCount = 0;//    then                then           promise      
        const results = new Array(promises.length)//       promises     ,       data
        return new MyPromise((resolve, reject) => {
            promises.forEach((promise, index) => {
                //   promise      promise
                promise = promise instanceof MyPromise ? promise : MyPromise.resolve(promise);
                promise.then(
                    data => {
                        results[index] = data;
                        resolveCount++
                        resolveCount === promises.length ? resolve(results) : null
                    },
                    error => reject(error) // all      reject   
                )
            })
        })
    }