//手写promise.js
const PENDING = 'PENDING';
const FULFILLEd = 'FULFILLEd';
const REJECTED = 'REJECTED';
const isPromise = (value) => {
if ((value != null && typeof value === 'object') || typeof value === 'function') {
if (typeof value.then == 'function') {
return true
}
} else {
return false
}
}
function getResolveValue(promiseNext, raw, resolve, reject) {
if (raw === promiseNext) {
return reject(new TypeError('不可返回同一个promise对象'))
}
let mark;
if ((typeof raw === 'object' && raw !== null) || typeof raw === 'function') {
try {
let then = raw.then;
if (typeof then === 'function') {
then.call(raw, function (next) {
if (mark) return;
mark = true;
getResolveValue(promiseNext, next, resolve, reject)
}, function (error) {
if (mark) return;
mark = true;
reject(error)
})
} else {
resolve(raw)
}
} catch (error) {
if (mark) return;
reject(error)
}
} else {
resolve(raw)
}
}
class SetPromise {
constructor(executor) {
this.status = PENDING;
this.value = null;
this.reason = null;
this.onSuccessCallback = [];
this.onRejectCallBack = [];
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error).bind(this)
}
}
static resolve(value){
if (isPromise(value)) {
return value
} else {
return new SetPromise((resolve, _) => {
resolve(value)
})
}
}
static reject(reason){
return new SetPromise((_, reject) => {
reject(reason)
})
}
static all(arr){
if (!Array.isArray(arr)) {
throw new TypeError('请传入一个数组')
}
return new SetPromise((resolve, reject) => {
try {
let resultArr = []
const length = arr.length
for (let i = 0; i < length; i++) {
arr[i].then(data => {
resultArr.push(data)
if (resultArr.length === length) {
resolve(resultArr)
}
}, reject)
}
} catch (error) {
reject(error)
}
})
}
static race(arr){
if (!Array.isArray(arr)) {
throw new TypeError('请传入一个数组')
}
return new SetPromise((resolve, reject) => {
try {
const length = arr.length
for (let i = 0; i < length; i++) {
arr[i].then(resolve, reject)
}
} catch (error) {
reject(error)
}
})
}
resolve(value) {
if (value instanceof SetPromise) {
return value.then(this.resolve, this.reject)
}
if (this.status === PENDING) {
this.status = FULFILLEd;
this.value = value;
this.onSuccessCallback.forEach(func => {
func(value)
})
}
}
reject(reason) {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
this.onRejectCallBack.forEach(func => {
func(reason)
})
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : data => data;
onRejected = typeof onRejected === 'function' ? onRejected : error => { throw (error) };
let promiseNext;
if (this.status === FULFILLEd) {
return promiseNext = new SetPromise((resolve, reject) => {
setTimeout(() => {
try {
let result = onFulfilled(this.value)
getResolveValue(promiseNext, result, resolve, reject)
} catch (error) {
reject(error)
}
})
})
} else if (this.status === REJECTED) {
return promiseNext = new SetPromise((resolve, reject) => {
setTimeout(() => {
try {
let result = onRejected(this.reason)
getResolveValue(promiseNext, result, resolve, reject)
} catch (error) {
reject(error)
}
})
})
} else if (this.status === PENDING) {
return promiseNext = new SetPromise((resolve, reject) => {
this.onSuccessCallback.push(value => {
try {
let result = onFulfilled(value)
getResolveValue(promiseNext, result, resolve, reject)
} catch (error) {
reject(error)
}
})
this.onRejectCallBack.push(reason => {
try {
let result = onRejected(reason)
getResolveValue(promiseNext, result, resolve, reject)
} catch (error) {
reject(error)
}
})
})
}
}
catch(err) {
return this.then(null, err)
}
finally(cb) {
return this.then((value) => {
return SetPromise.resolve(cb()).then(() => {
return value;
});
}, (err) => {
return SetPromise.resolve(cb()).then(() => {
throw err;
});
});
}
}
const p1 = new SetPromise((resolve, _) => {
setTimeout(() => {
resolve('p1')
}, 1000)
})
const p2 = new SetPromise((resolve, _) => {
setTimeout(() => {
resolve('p2')
}, 1000)
})
p1.then(res => {
console.log(res);
return p2;
}).then(res => console.log(res))
SetPromise.all([p1,p2]).then(res=>{console.log(0,res)})
new SetPromise((resolve, reject) => {
reject('错误')
}).catch(data => console.log(data)).finally(()=>console.log('finally'))
es6手写promise
最新推荐文章于 2023-02-01 11:22:55 发布