源码实现代码如下
class MyPromise {
constructor(executor){
if ( typeof executor != 'function' ) {
throw new Error('MyPromise must accept a function as a parameter')
}
//promise当前的状态
this.status = 'pending'
//promise的值
this.data = undefined
//promise resolve时的回调函数集,因为在promise结束之前可能有多个回调添加到它上面
this.onResolvedCallback = []
//promise reject时的回调函数集,因为在promise结束之前可能有多个回调添加到它上面
this.onRejectedCallback = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (err) {
this.reject(err)
}
}
resolve(value){
if ( this.status == 'pending' ) {
if ( value instanceof MyPromise ) {
value.then(res => {
this.status = 'fulfilled'
this.data = res
this.onResolvedCallback.forEach(callback => { callback(res) })
}, err => {
this.status = 'rejected'
this.data = err
this.onRejectedCallback.forEach(callback => { callback(err) })
})
} else {
this.status = 'fulfilled'
this.data = value
this.onResolvedCallback.forEach((callback)=>{callback(value)})
}
}
}
reject(reason){
if ( this.status == 'pending' ) {
this.status = 'rejected'
this.data = reason
this.onRejectedCallback.forEach((callback)=>{
callback(reason)
})
}
}
then(onResolved, onRejected){
onResolved = onResolved instanceof 'function' ? onResolved : value => value
onRejected = onRejected instanceof 'function' ? onRejected : reason => reason
if ( this.status === 'fulfilled' ) {
return new MyPromise((resolve, reject) => {
try {
let result = onResolved(this.data)
if ( result instanceof MyPromise ) {
result.then(resolve, reject)
}
resolve(result)
} catch (error) {
reject(error)
}
})
}
if ( this.status === 'rejected' ) {
return new MyPromise((resolve, reject)=>{
try {
let result = onRejected(this.data)
if ( result instanceof MyPromise ) {
result.then(resolve, reject)
}
resolve(result)
} catch (e) {
reject(e)
}
})
}
if ( this.status === 'pending' ) {
return new MyPromise((resolve, reject)=>{
this.onResolvedCallback.push((value)=>{
try {
let result = onResolved(this.data)
if ( result instanceof MyPromise ) {
result.then(resolve, reject)
}
resolve(result)
} catch (e) {
reject(e)
}
})
this.onRejectedCallback.push((reason)=>{
try {
let result = onRejected(this.data)
if ( result instanceof MyPromise ) {
result.then(resolve, reject)
}
resolve(result)
} catch (e) {
reject(e)
}
})
})
}
}
catch(onRejected){
return this.then(null, onRejected)
}
all(iterators){
let count = 0
let len = iterator.length
let res = []
return new MyPromise((resolve, reject)=>{
for (const i in iterators) {
MyPromise.resolve(iterators[i])
.then((data)=>{
res[i] = data
if ( ++count === len ) {
resolve(res)
}
})
.catch(e=>{
reject(e)
})
}
})
}
race(iterators){
return new MyPromise((resolve, reject)=>{
for (const p of iterators) {
MyPromise.resolve(p)
.then((res)=>{
resolve(res)
})
.catch(e => {
reject(e)
})
}
})
}
}
var promise1 = MyPromise.resolve(3);
var promise2 = new MyPromise(function(resolve, reject) {
setTimeout(resolve, 100, 'foo');
});
var promise3 = 42;
MyPromise.all([promise1, promise2, promise3]).then(function(values) {
console.log(values);
});
var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, 'one');
});
var promise2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then(function(value) {
console.log(value);
// Both resolve, but promise2 is faster
});
参考:
https://www.jianshu.com/p/b9ec2e3c3ad8
https://www.jianshu.com/p/90b6280dd1b6











网友评论