拓展-10【Promises/A+规范与源码重写】

(1).环境搭建

npm init -y

全局安装nodemon

设置运行命令

"scripts": {
    "dev":"nodemon ./index.js -i  ./data/"
  },

npm run dev

(2).完成一个基本的promise

MyPromise.js

const PENDING = 'PENDING',
      FULFILLED = 'FULFILLED',
      REJECTED = 'REJECTED';
class MyPromise{
    constructor(executor){
        this.status = PENDING;
        this.value = undefined;
        this.reason = undefined;
        const resolve = (value) =>{
            if(this.status === PENDING){
                this.status = FULFILLED;
                this.value = value;
            }
        } 
        const reject = (reason) => {
            if(this.status === PENDING){
                this.status = REJECTED;
                this.reason = reason
            }
        }
        try {
            executor(resolve,reject);            
        } catch (error) {
            reject(error)
        }
        
    }
    then(onFulfilled,onRejected){
        if(this.status === FULFILLED){
            onFulfilled(this.value);
        }
        if(this.status === REJECTED){
            onRejected(this.reason)
        }
    }
}      
module.exports = MyPromise;

index.js

const MyPromise = require('./MyPromise');
let promise = new MyPromise((resolve,reject)=>{
   // resolve('success')
  // reject('Error')
  throw new Error('Exception Erro')
})
promise.then((value)=>{
    console.log('FullFilled:'+value);
},(reason)=>{
    console.log('Rejected:'+reason)
})

(3).处理异步与多次调用

MyPromise1.js

const PENDING = 'PENDING',
      FULFILLED = 'FULFILLED',
      REJECTED = 'REJECTED';
class MyPromise{
    constructor(executor){
        this.status = PENDING;
        this.value = undefined;
        this.reason = undefined;

        this.onFulfiledCallbacks = [];
        this.onRejectedCallbacks = [];

        const resolve = (value) =>{
            if(this.status === PENDING){
                this.status = FULFILLED;
                this.value = value;
                //发布
                this.onFulfiledCallbacks.forEach(fn => fn())
            }
        } 
        const reject = (reason) => {
            if(this.status === PENDING){
                this.status = REJECTED;
                this.reason = reason
                //发布
                this.onRejectedCallbacks.forEach(fn => fn())
            }
            
        }

        try {
            executor(resolve,reject);            
        } catch (error) {
            reject(error)
        }
        
    }
    then(onFulfilled,onRejected){
        if(this.status === FULFILLED){
            onFulfilled(this.value);
        }
        if(this.status === REJECTED){
            onRejected(this.reason)
        }
        if(this.status === PENDING){
            //订阅
            this.onFulfiledCallbacks.push(()=>{
                onFulfilled(this.value)
            })
            this.onRejectedCallbacks.push(()=>{
                onRejected(this.reason)
            })
        }
    }
}      
module.exports = MyPromise;

index.js

const MyPromise = require('./MyPromise1');
let promise = new MyPromise((resolve,reject)=>{
   // resolve('success')
  // reject('Error')
  //throw new Error('Exception Erro')
  setTimeout(()=>{
    resolve('success')
  },300)
})
promise.then((value)=>{
    console.log('FullFilled:'+value);
},(reason)=>{
    console.log('Rejected:'+reason)
})

(4).原生promise链式调用特性总结

1.特性总结

catch在Promise的源码层面上就是一个then,catch也是遵循then的

成功的条件

then return 普通的 JavaScript value

then return 新的promise成功态的结果 value

失败的条件

then return 新的promise失败态的结果 reason

then 抛出异常 throw new Error

(5).链式调用功能

const PENDING = 'PENDING',
      FULFILLED = 'FULFILLED',
      REJECTED = 'REJECTED';
function resolvePromise(promise2,x,resolve,reject){
    console.log(x);
}      
class MyPromise{
    constructor(executor){
        this.status = PENDING;
        this.value = undefined;
        this.reason = undefined;

        this.onFulfiledCallbacks = [];
        this.onRejectedCallbacks = [];

        const resolve = (value) =>{
            if(this.status === PENDING){
                this.status = FULFILLED;
                this.value = value;
                //发布
                this.onFulfiledCallbacks.forEach(fn => fn())
            }
        } 
        const reject = (reason) => {
            if(this.status === PENDING){
                this.status = REJECTED;
                this.reason = reason
                //发布
                this.onRejectedCallbacks.forEach(fn => fn())
            }
            
        }

        try {
            executor(resolve,reject);            
        } catch (error) {
            reject(error)
        }
        
    }
    then(onFulfilled,onRejected){
        let promise2 = new MyPromise((resolve,reject)=>{
            if(this.status === FULFILLED){
                setTimeout(()=>{
                    try {
                        let x = onFulfilled(this.value)
                        resolvePromise(promise2,x,resolve,reject)
                    } catch (error) {
                        reject(e)
                    }
                },0)
            }
            if(this.status === REJECTED){
                setTimeout(()=>{
                    try {
                        let x = onRejected(this.value)
                        resolvePromise(promise2,x,resolve,reject)
                    } catch (error) {
                        reject(e)
                    }
                },0)
            }
            if(this.status === PENDING){
                //订阅
                this.onFulfiledCallbacks.push(()=>{
                    try {
                        let x =  onFulfilled(this.value);
                        resolvePromise(promise2,x,resolve,reject)
                    } catch (error) {
                        reject(error)
                    }
                  
                })
                this.onRejectedCallbacks.push(()=>{
                    try {
                        let x =  onRejected(this.value);
                        resolvePromise(promise2,x,resolve,reject)
                    } catch (error) {
                        reject(error)
                    }
                })
            }

        })
       return promise2
    }
}      
module.exports = MyPromise;

(6).resolvePromise

index.js

const MyPromise = require('./MyPromise2');
let promise = new Promise((resolve,reject)=>{
   resolve('success')
  // reject('Error')
  //throw new Error('Exception Erro')
//   setTimeout(()=>{
//     resolve('success')
//   },300)
})
let promise2 = promise.then(()=>{
    return 1;
},(reason)=>{
    return reason
})
promise2.then((value)=>{
    console.log(value);
   
},(reason)=>{
    console.log(reason)
})

MyPromise.js

const PENDING = 'PENDING',
      FULFILLED = 'FULFILLED',
      REJECTED = 'REJECTED';
let called = false      
function resolvePromise(promise2,x,resolve,reject){
    if(promise2 === x){
        return reject(new TypeError('返回重复'))
    }
    if((typeof x === 'object' && x !== null) || typeof x === 'function'){
        try {
            let then = x.then;
            if(typeof then === 'function'){
                then.call(x,(y)=>{
                    if(called) return;
                    called = true;
                    resolvePromise(promise2,y,resolve,reject);
                },(r)=>{
                    if(called) return;
                    called = true;
                    reject(r)
                })
            }else{
                resolve(x)
            }
        } catch (error) {
            if(called) return;
            called = true;
            reject(e)
        }
    }else{
        resolve(x)
    }
}      

class MyPromise{
    constructor(executor){
        this.status = PENDING;
        this.value = undefined;
        this.reason = undefined;

        this.onFulfiledCallbacks = [];
        this.onRejectedCallbacks = [];

        const resolve = (value) =>{
            if(this.status === PENDING){
                this.status = FULFILLED;
                this.value = value;
                //发布
                this.onFulfiledCallbacks.forEach(fn => fn())
            }
        } 
        const reject = (reason) => {
            if(this.status === PENDING){
                this.status = REJECTED;
                this.reason = reason
                //发布
                this.onRejectedCallbacks.forEach(fn => fn())
            }
            
        }

        try {
            executor(resolve,reject);            
        } catch (error) {
            reject(error)
        }
        
    }
    then(onFulfilled,onRejected){
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled:value => value
        onRejected = typeof onRejected === 'function' ? onRejected: reason =>  {throw reason}
        let promise2 = new MyPromise((resolve,reject)=>{
            if(this.status === FULFILLED){
                setTimeout(()=>{
                    try {
                        let x = onFulfilled(this.value)
                        resolvePromise(promise2,x,resolve,reject)
                    } catch (error) {
                        reject(e)
                    }
                },0)
            }
            if(this.status === REJECTED){
                setTimeout(()=>{
                    try {
                        let x = onRejected(this.value)
                        resolvePromise(promise2,x,resolve,reject)
                    } catch (error) {
                        reject(e)
                    }
                },0)
            }
            if(this.status === PENDING){
                //订阅
                this.onFulfiledCallbacks.push(()=>{
                    try {
                        let x =  onFulfilled(this.value);
                        resolvePromise(promise2,x,resolve,reject)
                    } catch (error) {
                        reject(error)
                    }
                  
                })
                this.onRejectedCallbacks.push(()=>{
                    try {
                        let x =  onRejected(this.value);
                        resolvePromise(promise2,x,resolve,reject)
                    } catch (error) {
                        reject(error)
                    }
                })
            }

        })
       return promise2
    }
    catch(errorCallback){
        return this.then(null,errorCallback)
    }
}      
module.exports = MyPromise;

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页