简易TS版手写Promise通俗易懂,简单的爆
大约 5 分钟
Promise
通俗易懂,简单的爆
简易TS版手写promise
的类,结合现有的promise
第一步简单定义一下基本属性,准备一个定义其属性
当前状态 status
一个成功的回调函数
resolve
一个失败的函数
reject
一个外面的传入值
rejectResolveValue
// 声明部分
type resolveType = (value: string) => void
type rejectType = (value: string) => void
// 根据promise 用法, 会回调两个函数
type Excuted = (resolve: resolveType, reject: rejectType) => void
// 实现部分
class newPromise<T = any> {
public reject !: rejectType
public resolve!: resolveType
public status!: 'pending' | 'success' | 'fail'; // 这里固定pending success fail 3种
public rejectResolveValue!: any; // 的值
constructor(exce: Excuted) {
this.status = 'pending'
this.reject = (val: any) => {
this.status = 'fail'
this.rejectResolveValue = val;
}
this.resolve = (val: any) => {
this.status = 'success'
this.rejectResolveValue = val;
}
try {
exce(this.resolve, this.reject)
} catch (error) {
this.reject(error as any)
}
}
}
// 测试部分
let myPro = new newPromise((resolve, reject) => {
// resolve("初始化数据")
reject("失败")
})
第二步. 实现then方法
类里面加一个then()的方法,传入两个方法,
判断状态是否改变,选择执行,成功还是失败
class newPromise<T = any> {
// ....
then(resolve: resolveType, reject: resolveType) {
let result: any // 定义一个变量result 来接收值
if(this.status === 'success'){ // 这个地方只要是为了有先后顺序, 只要实例化对象那里,根据上面的状态改变,来执行
....
}
if(this.status === 'fail'){ // 这个地方只要是为了有先后顺序, 只要实例化对象那里,根据上面的状态改变,来执行
....
}
}
}
第二步. 实现then方法的连续调用
我们通过返回一个
newPromise
对象重复上面的工作
class newPromise<T = any> {
// ....
then(resolve: resolveType, reject: resolveType) {
return new newPromise((resolve2, reject2) => {
// 定义一个变量result 来接收值
let result: any
// 这个地方只要是为了有先后顺序, 只要实例化对象那里,根据上面的状态改变,来执行
if(this.status === 'success'){
// 回炉重造
result = resolve(this.rejectResolveValue)
// 返回成功值
resolve2(result)
}
// 这个地方只要是为了有先后顺序, 只要实例化对象那里,根据上面的状态改变,来执行
if(this.status === 'fail'){
// 回炉重造
result = resolve(this.rejectResolveValue)
// 返回失败值
reject(result)
}
}
}
}
第三步. 开始处理异步操作, 如果一直为pending怎么半
我们在类里面多加一个属性来存储我们将要执行的方法.等到我的异步事件执行完后,我们再依次执行
type callFunction = () => any
class newPromise<T = any> {
// 用来存储成功或失败函数
public resolveCallList: callFunction[] = [];
public rejectCallList: callFunction[] = [];
// ....
then(resolve: resolveType, reject: resolveType) {
return new newPromise((resolve2, reject2) => {
// 定义一个变量result 来接收值
let result: any
// 这个地方只要是为了有先后顺序, 只要实例化对象那里,根据上面的状态改变,来执行
if(this.status === 'success'){
// 回炉重造
result = resolve(this.rejectResolveValue)
// 返回成功值
resolve2(result)
}
// 这个地方只要是为了有先后顺序, 只要实例化对象那里,根据上面的状态改变,来执行
if(this.status === 'fail'){
// 回炉重造
result = resolve(this.rejectResolveValue)
// 返回失败值
reject(result)
}
if (this.status === "pending") { // 这里开始处理异步事件
this.resolveCallList.push(() => {
let result: any = resolve(this.rejectResolveValue)
resolve2(result)
})
this.rejectCallList.push(() => {
reject2(reject(this.rejectResolveValue) as any)
})
}
}
}
}
第三步(附加). 上述情况们只讨论了返回一个值的情况,如果then函数里面返回了一个Promise怎么办?
判断一下是否是
newPromise
对象即可,然后回炉重造
// 这个地方来判断是否是穿进来的promise 对象
function isPromise(val: any): val is newPromise {
return isObject(val) && isFunction(val.then)
}
function isObject(val: any): val is Record<any, any> {
return val !== null && typeof val === 'object'
}
function isFunction(val: any): val is Function {
return typeof val === "function"
}
// ...
if (this.status === "pending") {
this.resolveCallList.push(() => {
let result: any = resolve(this.rejectResolveValue)
if (isPromise(result)) {
result.then(
(val) => {
resolve2(val)
},
(val) => {
reject2(val)
})
} else {
resolve2(result)
}
}
}
/....
promise.all()
的用法
第四步,实现传入多个promise对象, 我们吧每个promise异步或同步操作的值全部返回到一个列表中,然后通过then方法获取到值
all()实现方法:
定义一个静态方法
接收多个promise ,
返回一个promise 回炉重造即可
static all(Promises: newPromise[]): newPromise { // 输入多个promise ,返回一个
return new newPromise((resolve, reject) => {
// 定义一个列表用来保存每个处理结果后值
let resRejDatalist: any[] = [];
Promises.forEach((promise, index) => { // 这里循环调用每个promise
promise.then(
res => {
console.log(res);
processPromiseData(res, index)
},
rej => {
reject(rej);
return
}
)
})
function processPromiseData(val: any, index: number) { // 如果每个promise都处理放在我们就返回数据
resRejDatalist[index] = val;
if (Promises.length - 1 === index) {
resolve(resRejDatalist as any)
}
}
})
}
完整代码
type callFunction = () => any
type resolveType = (value: string) => void
type rejectType = (value: string) => void
type Excuted = (resolve: resolveType, reject: rejectType) => void
class newPromise<T = any> {
public reject !: rejectType
public resolve!: resolveType
public status!: 'success' | 'fail' | "pending"
public rejectResolveValue!: any;
public resolveCallList: callFunction[] = [];
public rejectCallList: callFunction[] = [];
constructor(exce: Excuted) {
this.status = 'pending'
this.reject = (val: any) => {
this.status = 'fail'
this.rejectResolveValue = val;
this.rejectCallList.forEach(voild => voild())
}
this.resolve = (val: any) => {
this.status = 'success'
this.rejectResolveValue = val;
this.resolveCallList.forEach(voild => voild())
}
try {
exce(this.resolve, this.reject)
} catch (error) {
this.reject(error as any)
}
}
then(resolve: resolveType, reject: resolveType) {
return new newPromise((resolve2, reject2) => {
let result: any;
console.log(this.status, 'this.status');
if (this.status === 'success') {
result = resolve(this.rejectResolveValue)
console.log(typeof result);
console.log(typeof result.then);
resolve2(result)
}
if (this.status === 'fail') {
result = resolve(this.rejectResolveValue)
reject(result)
}
if (this.status === "pending") {
this.resolveCallList.push(() => {
let result: any = resolve(this.rejectResolveValue)
if (isPromise(result)) {
result.then(
(val) => {
resolve2(val)
},
(val) => {
reject2(val)
})
} else {
resolve2(result)
}
})
// 这里不想改了, 和成功一样要判断isPromise
this.rejectCallList.push(() => {
reject2(reject(this.rejectResolveValue) as any)
})
}
})
}
static all(Promises: newPromise[]): newPromise {
return new newPromise((resolve, reject) => {
// 定义一个列表用来保存每个处理结果后值
let resRejDatalist: any[] = [];
Promises.forEach((promise, index) => {
promise.then(
res => {
console.log(res);
processPromiseData(res, index)
},
rej => {
reject(rej);
return
}
)
})
function processPromiseData(val: any, index: number) {
resRejDatalist[index] = val;
if (Promises.length - 1 === index) {
resolve(resRejDatalist as any)
}
}
})
}
}
// 这个地方来判断是否是穿进来的promise 对象
function isPromise(val: any): val is newPromise {
return isObject(val) && isFunction(val.then)
}
function isObject(val: any): val is Record<any, any> {
return val !== null && typeof val === 'object'
}
function isFunction(val: any): val is Function {
return typeof val === "function"
}