前言
如题 手写Promise
const PENDING = 'pending'
const RESOLVED = 'resloved'
const REJECTED = 'rejected'
class Promise {
constructor(fn){
this.state = PENDING
this.value = undefined
this.resolveCallback = []
this.rejectCallback = []
const resolve = (value)=>{
if(value instanceof Promise){
return value.then((v)=>{resolve(v)})
}
if(this.state === PENDING){
this.state = RESOLVED
this.value = value
this.resolveCallback.forEach(cb => cb())
}
}
const reject =(val)=>{
if(this.state === PENDING){
this.state = REJECTED
this.value = value
this.rejectCallback.forEach(cb => cb())
}
}
try{
fn(resolve,reject)
}
catch(e){
reject(e)
}
}
then(onFullFilled,onRejected){
onFullFilled = typeOf onFullFilled === 'function'? onFullFilled: v=> v;
onRejected = typeOf onRejected === 'function'? onRejected: err=> { throw err};
let promise2 = new Promise((resolve,reject)=>{
if(this.state === PENDING){
this.resolveCallback.push(()=>{
setTimeout(()=>{
try{
const x = onFullFilled(this.value)
resolvePromise(promise2,x,resolve,reject)
}catch(err){
reject(err)
}
},0)
})
this.rejectCallback.push(()=>{
setTimeout(()=>{
try{
const x = onRejected(this.value)
resolvePromise(promise2,x,resolve,reject)
}catch(err){
reject(err)
}
},0)
})
}
if(this.state === RESOLVED){
setTimeout(()=>{
try{
const x = onFullFilled(this.value)
resolvePromise(promise2,x,resolve,reject)
}catch(err){
reject(err)
}
},0)
}
if(this.state === REJECTED){
setTimeout(()=>{
try{
const x = onRejected(this.value)
resolvePromise(promise2,x,resolve,reject)
}catch(err){
reject(err)
}
},0)
}
})
return promise2
}
catch(val){
return Promise.reject(val)
}
}
Promise.resolve = function(val){
return new Promise((reslove,reject)=>{
resolve(val)
})
}
Promise.reject = function(val){
return new Promise((reslove,reject)=>{
reject(val)
})
}
Promise.all = function(promises){
let pArr = []
let i = 0
function dealRespromiseData(i,data,resolve){
pArr[i] = data
i++
if(i === promises.length){
resolve(pArr)
}
}
return new Promise((resolve,reject)=>{
promises.forEach((p,index)=>{
p.then(val =>{
dealRespromiseData(index,val,resolve)
})
})
})
}
Promise.race = function(promises){
return new Promise((resolve,reject)=>{
promises.forEach(p=>{
p.then(val=>{
reslove(val)
})
})
})
}
function resolvePromise(promise2,x,resolve,reject){
if(promise2 === x){
return reject(new Error('can not be same value'))
}
let called = false
if(x!==null && (typeOf x === 'object' ||typeOf x === 'function') ){
const then = x.then
if( then === 'function'){
try{
then.call((
x,
(y)=>{
if(called) return
called = true
resolvePromise(promise2,y,resolve,reject)
},
(err)=>{
if(called) return
called = true
reject(err)
},
))
}
catch(e){
if(called) return
called = true
reject(err)
}
}else{
resolve(x)
}
}else{
resolve(x)
}
}
验证我们的promise是否正确
- 先在后面加上下述代码
- npm 有一个promises-aplus-tests插件 npm i promises-aplus-tests -g 可以全局安装 mac用户最前面加上sudo
-
命令行 promises-aplus-tests [js文件名] 即可验证
Promise.defer = Promise.deferred = function () { // npm install promises-aplus-tests 用来测试自己的promise 符不符合promisesA+规范 // 目前是通过他测试 他会测试一个对象 // 语法糖 let dfd = {} dfd.promise = new Promise((resolve,reject)=>{ dfd.resolve = resolve; dfd.reject = reject; }); return dfd; } module.exports = Promise;