Promise 原理解析
es5实现方案
js
// 参考: https://juejin.im/post/5aab286a6fb9a028d3752621#heading-3
// 三个状态,pending只能扭转成一个状态
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
function Promise(executor) {
console.log('-------------------Promise_es5-------------------')
let self = this
self.status = PENDING // 初始为pending
self.data = undefined // 成功或失败的值
self.callbacks = [] // 执行器中为异步时保存的回调
function resolve(value) {
if(self.status !== PENDING) return;
self.status = RESOLVED
self.data = value
if(self.callbacks.length > 0) self.callbacks.forEach(fn => fn.onFulfiled(value))
}
function reject(reason) {
if(self.status !== PENDING) return;
self.status = REJECTED
self.data = reason
if(self.callbacks.length > 0) self.callbacks.forEach(fn => fn.onRejected(reason))
}
try{
executor(resolve, reject) // 同步执行Promise内回调,捕获错误传给reject
} catch(err) {
reject(err)
}
}
// 1、返回一个新的Promise
// 2、返回的Promise结果由onfulfilled或onRejected决定
Promise.prototype.then = function (onFulfiled, onRejected) {
let self = this
onFulfiled = typeof(onFulfiled) === 'function' ? onFulfiled : value => value // value为普通值,传啥进去,return啥出来,见行40(值的穿透)
onRejected = typeof(onRejected) === 'function' ? onRejected : reason => {throw reason}
return new Promise((resolve, reject) => {
function handle(cb) {
try {
let res = cb(self.data)
if(res instanceof Promise) {
// res.then(value => resolve(value), reason => reject(reason))
res.then(resolve, reject) // 简写
}else{
resolve(res) // 非Promise对象resolve res即可(上面已经调用过一次了)
}
} catch (err) {
reject(err)
}
}
if(self.status === RESOLVED) {
handle(onFulfiled)
}
if(self.status === REJECTED) {
handle(onRejected)
}
if(self.status === PENDING) { // 如果执行到.then的时候还没resovle或者reject则先保存回调
self.callbacks.push({
onFulfiled() {
handle(onFulfiled)
},
onRejected() {
handle(onRejected)
}
})
}
})
}
// 返回的不是一个新的Promise,只是一个上一个then放回的Promise,只是修改里面的内容
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
// 实现静态方法
Promise.resolve = function (value) {
return new Promise((resolve, reject) => {
if(value instanceof Promise){
value.then(resolve, reject)
}else {
resolve(value)
}
})
}
Promise.reject = function (reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
Promise.all = function (promises) {
if(!(promises instanceof Array)) throw new Error('传个数组,老铁')
let valueArr = new Array(promises.length), // 与all中数组等长的数组
resolveCount = 0;
return new Promise((resolve, reject) => {
promises.forEach((p, i) => {
// Promise.resolve(p): p要包一层的原因是p有可能不是一个promise对象,于是包一层就好了,不用做多余的判断
Promise.resolve(p).then(value => {
// valueArr.push(value) // 不能用push,用push不能保证顺序
valueArr[i] = value
resolveCount++
if(resolveCount === promises.length) resolve(valueArr)
}, reason => {
reject(reason)
})
})
})
}
Promise.race = function (promises) {
if(!(promises instanceof Array)) throw new Error('传个数组,老铁')
return new Promise((resolve, reject) => {
promises.forEach((p, i) => {
// Promise.resolve(p): p要包一层的原因是p有可能不是一个promise对象,于是包一层就好了,不用做多余的判断
Promise.resolve(p).then(value => {
resolve(value) // 假如第一个成功的立即resolve
}, reason => {
reject(reason) // 假如第一个失败的立即reject
})
})
})
}
// 自定义延时回调的方法
// value为resolve的值, time为延时执行的时间
Promise.resolveDelay = function (value, time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if(value instanceof Promise) { // 判断一下是否是Promise实例,是则取其value值
value.then(resolve, reject)
}else{
resolve(value) // 不是则直接resolve
}
}, time)
})
}
Promise.rejectDelay = function (reason, time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(reason) // 延迟后返回一个失败的Promise实例
}, time)
})
}
// 实现一个promise的延迟对象 defer
// 此步是为了测试我们手写的Promsie符不符合Promsie/A+规范,如果没有defer的话,我们在测试过程中就会报一个TypeError: adapter.deferred is not a function.
Promise.defer = Promise.deferred = function(){
let dfd = {};
dfd.promise = new Promise((resolve, reject)=>{
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
}
// module.exports = Promise
es6实现方案
js
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTD = 'rejected'
export default class Promise{
constructor(executor) {
// console.log('-------------------Promise_es6-------------------')
this.state = PENDING
this.data = undefined
this.callbacks = []
let self = this
function resolve(value) {
if(self.state !== PENDING) return; // 状态只能改变一次,如果不是PENDING过渡过来直接return,reject同。
self.state = RESOLVED
self.data = value
if(self.callbacks.length > 0) self.callbacks.forEach(fn => fn.onResolved())
}
function reject(reason) {
if(self.state !== PENDING) return;
self.state = REJECTD
self.data = reason
if(self.callbacks.length > 0) self.callbacks.forEach(fn => fn.onRejected())
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
then(onResolved, onRejected) {
// console.log(typeof(onResolved) === 'function')
// 如果两个参数不是函数,则会在内部被替换为 (x) => x,即原样返回 promise 最终结果的函数
onResolved = typeof(onResolved) === 'function' ? onResolved : value => value // 普通值穿透
onRejected = typeof(onRejected) === 'function' ? onRejected : reason => {throw reason} // 普通值穿透
let self = this
return new Promise((resolve, reject) => { // 1、then返回新的Promise对象,但是要注意它的返回值
function handle(cb) {
try {
let res = cb(self.data) // 2、返回值
if(res instanceof Promise) { // 3、如果返回的Promise对象,通过then获取其值
// res.then(value => resolve(value), reason => reject(reason))
res.then(resolve, reject) // 简写,同上
}else { // 非Promise对象,直接resolve
resolve(res)
}
} catch (error) {
reject(error)
}
}
if(self.state === RESOLVED) {
// 模拟异步
setTimeout(() => {
handle(onResolved)
})
}
if(self.state === REJECTD) {
setTimeout(() => {
handle(onRejected)
})
}
if(self.state === PENDING) { // 如果这里还是PENDING,说明executor里面有异步操作,先把回调保存起来
self.callbacks.push({
onResolved() {
handle(onResolved)
},
onRejected() {
handle(onRejected)
}
})
}
})
}
catch(errCb) {
return this.then(undefined, errCb)
}
// Promise静态方法的实现(返回的是Promise对象)
static resolve(value) {
return new Promise((resolve, reject) => {
if(value instanceof Promise) {
value.then(value => resolve(value), reason => reject(reason))
}else {
resolve(value)
}
})
}
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
static all(promises) {
let res = new Array(promises.length),
count = 0
return new Promise((resolve, reject) => {
promises.forEach((p, i) => {
// Promise.resolve(p):防止promises中存在非Promise值
Promise.resolve(p).then(value => {
res[i] = value
// 注意一下下面两行代码,不要写到then外面去了!!!
count++
if(count === promises.length) resolve(res)
}, reason => {
reject(reason)
})
})
})
}
static race(promises) {
return new Promise((resolve, reject) => {
promises.forEach(p => {
Promise.resolve(p).then(value => {
resolve(value) // 返回最快的那个即可
}, reason => {
reject(reason)
})
})
})
}
// 自定义的静态方法:指定时间延迟执行
static resolveDelay(value, time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if(value instanceof Promise) {
// value.then(resolve, reject)
value.then(value => resolve(value), reason => reject(reason))
}else {
resolve(value)
}
}, time)
})
}
static rejectDelay(reason, time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(reason)
}, time)
})
}
}
// 测试方法
Promise.defer = Promise.deferred = function(){
let dfd = {};
dfd.promise = new Promise((resolve, reject)=>{
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
}
// module.exports = Promise