回顾上一篇文章的Promise的实现,Promise的三种状态pending,fulfilled,fail Promise两个参数,resolve,reject Promise实现第一步------- Promise回调实现
- actiontype 新建一个actiontype.ts,并且初始化tsconfig.json,package.json
// 返回值可以是void,但是用any? 因为any包含void
type ResolveType = (resolve: any) => any
type RejectType = (reject: any) => any
type Executor = (resolve: ResolveType, reject: RejectType) => any
export { ResolveType, RejectType, Executor }
- Promise回调实现 新建promise.ts
import { ResolveType, RejectType, Executor } from './actiontype'
class Promise<T = any> {
public resolve!: ResolveType
public reject!: RejectType
public status!: string // 状态
public resolve_executor_value!: any
public reject_executor_value!: any
constructor(executor: Executor) {
this.status = "pending" //初始状态
this.resolve = (success_value: any): any => {
if(this.status === 'pending') {
this.status = 'fulfilled'
this.resolve_executor_value = success_value
console.log('fulfilled')
}
}
this.reject = (fail_value: any): any => {
if(this.status === 'pending') {
this.status = 'fail'
this.reject_executor_value = fail_value
console.log('fail')
}
}
executor(this.resolve, this.reject)
}
then(resolveInThen: ResolveType, rejectInThen: RejectType) {
if(this.status === 'fulfilled') {
resolveInThen(this.resolve_executor_value)
console.log('resolveInThen')
}
if(this.status === 'fail') {
rejectInThen(this.reject_executor_value)
console.log('rejectInThen')
}
}
}
export default Promise
- 测试类实现 新建test.ts 并在package.json中添加 "tsc": "ts-node ./test.ts"
import Promise from './Promise'
let promise = new Promise((resolve, reject) => {
resolve('成功了')
reject('失败了')
})
promise.then(resolveData => {
console.log('resolveData', resolveData)
}, (rejectData) => {
console.log('rejectData', rejectData)
})
报错的实现,发生异常的处理,可以使用try{}catch {}捕获异常
try {
executor(this.resolve, this.reject)
} catch (err: any) {
this.status = 'pending'
this.reject(err.toString())
throw new Error("程序终止...")
}
Promise完整版的代码如下:
import { ResolveType, RejectType, Executor } from './actiontype'
class Promise<T = any> {
public resolve!: ResolveType
public reject!: RejectType
public status!: string // 状态
public resolve_executor_value!: any
public reject_executor_value!: any
constructor(executor: Executor) {
this.status = "pending" //初始状态
this.resolve = (success_value: any): any => {
if(this.status === 'pending') {
this.status = 'fulfilled'
this.resolve_executor_value = success_value
}
}
this.reject = (fail_value: any): any => {
if(this.status === 'pending') {
this.status = 'fail'
this.reject_executor_value = fail_value
}
}
try {
executor(this.resolve, this.reject)
} catch (err: any) {
this.status = 'pending'
this.reject(err.toString())
throw new Error("程序终止...")
}
}
then(resolveInThen: ResolveType, rejectInThen: RejectType) {
if(this.status === 'fulfilled') {
resolveInThen(this.resolve_executor_value)
}
if(this.status === 'fail') {
rejectInThen(this.reject_executor_value)
}
}
}
export default Promise
同步级联then方法的实现 要实现的效果如下: test.ts
promise.then(resolveData => {
console.log('resolveData', resolveData)
return 'ok'
}, (rejectData) => {
console.log('rejectData', rejectData)
return 'fail'
}).then((resolveData2) => {
console.log('resolveData2', resolveData2)
return 'ok2'
}, (rejectData2) => {
console.log('rejectData', rejectData2)
return 'fail2'
}).then((resolveData3) => {
console.log('resolveData3', resolveData3)
return 'ok3'
}, (rejectData3) => {
console.log('rejectData', rejectData3)
return 'fail3'
})
要想实现同步级联,首先then里面必须传入一个Promise,用一个变量接受resolve函数的值,完整的then代码如下:
then(resolveInThen: ResolveType, rejectInThen: RejectType) {
let result
.2 return new Promise((resolve, reject) => {
console.log('this', this) // 此时的this指的是最外面的p
if(this.status === 'fulfilled') {
result = resolveInThen(this.resolve_executor_value)
.4 resolve(result)
}
if(this.status === 'fail') {
result = rejectInThen(this.reject_executor_value)
reject(result)
}
})
}
补充解释: 当我们执行上面代码2行的时候,new Promise会再次调用constructor里面executor执行器,并传递resolve和reject到executor,那么此时的this是谁?此时的this指的是最外面的p;4行的resolve怎么解释呢?会再次调用resolve方法,并且把result传递过去,此时的resolve方法是本次new Promise产生的,所以会存储在本次的resolve_executor_value上,依次循环.
Promise第二部---------异步 看看异步的场景
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('成功')
reject('失败)
}, 5)
})
用订阅和发布来实现上述场景
public resolve_then_callbacks: (() => void)[] = []
public reject_then_callbacks: (() => void)[] = []
if(this.status === 'pending') {
// 订阅
this.resolve_then_callbacks.push(() => {
result = resolveInThen(this.resolve_executor_value)
resolve(result)
})
this.reject_then_callbacks.push(() => {
result = rejectInThen(this.reject_executor_value)
reject(result)
})
}
多个异步怎么操作 第一种实现方式
promise.then(resolveData => {
console.log('resolveData', resolveData)
// 怎么实现
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('成功了promise.then')
}, 5)
})
}, (rejectData) => {
console.log('rejectData', rejectData)
return 'fail'
})
实现方式,怎么判断是promise类型的
function isPromise(val: any): val is Promise {
return isObject(val) && isFunction(val.then)
}
function isObject(val: any): val is Record<any, any> {
return val !== null && typeof val === 'object'
}
function isFunction(data: any): data is Function {
return typeof data === "function"
}
使用setTImeout解决方案
if(this.status === 'pending') {
// 订阅
this.resolve_then_callbacks.push(() => {
result = resolveInThen(this.resolve_executor_value)
if(isPromise(result)) { // promise
// 先执行promise,再setTimeout
setTimeout(() => {
resolve(result.resolve_executor_value)
}, 5)
} else {
resolve(result) // 普通的数据
}
})
this.reject_then_callbacks.push(() => {
result = rejectInThen(this.reject_executor_value)
reject(result)
})
}
优化上述代码:
if(this.status === 'pending') {
// 订阅
this.processManyAsyncAndSync(resolveInThen, rejectInThen, resolve, reject)
}
processManyAsyncAndSync(resolveInThen: ResolveType, rejectInThen: RejectType, resolve: ResolveType, reject: RejectType) {
let result: any
this.resolve_then_callbacks.push(() => {
result = resolveInThen(this.resolve_executor_value)
if(isPromise(result)) { // promise
// 先执行promise,再setTimeout
setTimeout(() => {
resolve(result.resolve_executor_value)
}, 5)
} else {
resolve(result) // 普通的数据
}
})
this.reject_then_callbacks.push(() => {
result = rejectInThen(this.reject_executor_value)
reject(result)
})
}
第二种实现方案
processManyAsyncAndSync(resolveInThen: ResolveType, rejectInThen: RejectType, resolve: ResolveType, reject: RejectType) {
let result: any
this.resolve_then_callbacks.push(() => {
result = resolveInThen(this.resolve_executor_value)
if(isPromise(result)) { // promise
// 先执行promise,再setTimeout
result.then((resolveSuccess) => {
resolve(resolveSuccess)
}, (rejectSuccess) => {
reject(rejectSuccess)
})
} else {
resolve(result) // 普通的数据
}
})
this.reject_then_callbacks.push(() => {
result = rejectInThen(this.reject_executor_value)
reject(result)
})
}
手写Promise.all实现
static all(promises: Promise[]): Promise {
return new Promise((resolve, reject) => {
let allPromiseResolveValue: Array<any> = []
promises.forEach((promise, index) => {
promise.then((resolveSuccess) => {
ProcessData(resolveSuccess, index)
}, (rejectFail) => {
reject(rejectFail) // 只要有一个promise对象的resolve执行失败
return
})
})
function ProcessData(resolveSuccess: any, index: number) {
allPromiseResolveValue[index] = resolveSuccess
if(index === promises.length - 1) { // 所有的promise对象resolve函数全部执行完毕
resolve(allPromiseResolveValue)
}
}
})
}
测试案例
const promise1 = new Promise((resolve, reject) => {
console.log('第一个promise同步区域')
setTimeout(() => {
resolve('setTimeout第一个promise')
}, 5)
})
const promise2 = new Promise((resolve, reject) => {
console.log('第二个promise同步区域')
setTimeout(() => {
resolve('setTimeout第二个promise')
}, 5)
})
const promise3 = new Promise((resolve, reject) => {
console.log('第三个promise同步区域')
setTimeout(() => {
resolve('setTimeout第三个promise')
}, 5)
})
Promise.all([promise1, promise2, promise3]).then(resolveValue => {
console.log(resolveValue)
}, rejectValue => {
console.log(rejectValue)
})
all只要有一个reject,然后终止并返回reject的promise