🏃🏻 最近复习了一下Promise相关知识点,顺便自己简单的手写实现一个Promise和链式调用
- 实现Promise()
const PENDING = 'pending';
const RESOLVED = 'resolved';
const REJECTED = 'rejected';
function MyPromise(fn) {
this.status = PENDING;
this.value = null;
this.reason = null;
this.resolvedCallbacks = [];
this.rejectedCallbacks = [];
const resolve = (value) => {
if (this.status === PENDING) {
this.status = RESOLVED;
this.value = value;
setTimeout(() => {
this.resolvedCallbacks.map(cb => cb());
})
}
}
// reject实现原理同上
const reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
setTimeout(() => {
this.rejectedCallbacks.map(cb => cb());
})
}
}
try {
fn(resolve, reject);
} catch (e) {
reject(e);
}
}
// then/catch
MyPromise.prototype.then = function (onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
this.resolvedCallbacks.push(() => {
const res = onFulfilled(this.value)
if (res instanceof MyPromise) {
res.then(resolve, reject)
} else {
resolve(res)
}
});
// reject实现原理同上
this.rejectedCallbacks.push(() => {
const res = onRejected(this.reason)
if (res instanceof MyPromise) {
res.then(resolve, reject)
} else {
reject(res)
}
});
})
}
// 使用
const p = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('successMsg-p');
// reject('errInfo-p');
}, 1000);
});
const p1 = p.then((res) => {
console.log('res:', res)
return p2
}, (err) => {
console.log('err: ', err);
})
// user promise
const p2 = new MyPromise((resolve) => {
setTimeout(() => {
resolve('successMsg-p2');
}, 500)
})
// 链式调用
new MyPromise((resolve) => {
setTimeout(() => {
resolve(1)
}, 5000)
})
.then((res) => {
console.log(res); // 1
return new MyPromise((resolve) => { // user promise
setTimeout(() => {
resolve(2);
}, 2000);
});
})
.then(console.log) // 2
- 实现promise.resolve()
// resolve
MyPromise.resolve = function (data) {
// 1. 参数是一个 Promise 实例,不做任何修改、原封不动地返回这个实例
if (data instanceOf MyPromise) {
return data
}
// 2. 参数是一个thenable对象,将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。
if (data.then) {
return new MyPromise((resolve, reject) => {
data.then(resolve, reject)
})
}
// 3. 参数不是具有then方法的对象,或根本就不是对象
// 4. 不带有任何参数
return new MyPromise((resolve) => {
resolve(data)
})
}
- 实现promise.all()
// all
MyPromise.all = (promises) => {
let arr = [], count = 0;
return new Promse((resolve, reject) => {
promises.forEach((item, i) => {
MyPromise.resolve(item).then(res => {
arr[i] = res;
count += 1;
if (count === promise.length) resolve(arr)
}, reject)
})
})
}
- 实现promise.allSettled()
// allSettled
MyPromise.allSettled = (promised) => {
let arr = [], count = 0
const processResult = (res, index, status) => {
arr[index] = { status: status, val: res }
count += 1
if (count === promises.length) resolve(arr)
}
promises.forEach((item, i) => {
MyPromise.resolve(item).then(res => {
processResult(res, i, 'fulfilled')
}, err => {
processResult(err, i, 'rejected')
})
})
}
- 实现promise.race()
// race
MyPromise.race = (promises) => {
return new MyPromise((resolve, reject) => {
promises.forEach((item) => {
MyPromise.resolve(item).then(resolve, reject)
})
})
}
- 实现promise.any()
// any
MyPromise.any = (promises) => {
let arr = [], count = 0;
return new MyPromise((resolve, reject) => {
promises.forEach((item, i) => {
MyPromise.resolve(item).then(resolve, () => {
arr[i] = { status: 'rejected', val: err }
count += 1;
if (count = arr.length) {
reject(new AggregateError(arr, 'All promises were rejected'))
}
})
})
})
}
👉 本代码仅供参考,欢迎各位大佬有好的想法或建议可以留言,后续再回来更改优化~~
(仅考虑了如何简单实现过程,没有考虑太多细节🙌)
✍️ 感兴趣的话可以阅读 Promise A+ 规范 promisesaplus.com/