需要实现的功能:
promise的实现机制:
new Promise((resolve,reject) => {
// 立即执行
})
// 三种状态
const PENDDING = "pendding"
const FULLFILED = "fullfied"
const REJECT = "reject"
function resolvePromise(thenPromise, preResult, resolve, reject) {
if (thenPromise === preResult) return reject(new Error('循环引用'))
// 1. 如果上一次then中任务执行返回值preResult是一个对象或者function
// a. 对象,直接resolve
// b. function且是一个Promise,则递归调用
// 2. 普通数据则直接resolve
let x = preResult, called = false;
if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
let then = x.then
try {
// a. 如果是Promise ,调用then方法
if (typeof then === 'function') {
// console.log('promise')
if (called) return
called = true
then.call(x, val => {
// console.log("返回值",val)
resolvePromise(thenPromise, val, resolve, reject)
}, err => {
if (called) return
called = true
reject(err)
})
} else { // b. 如果是普通的对象
// console.log('普通对象')
resolve(x)
}
} catch (err) {
if (called) return
called = true
reject(err)
}
} else {
// console.log("基本数据或者undefined原样返回")
resolve(x)
}
}
class ZPromise {
static resolve(value) {
return new ZPromise((resolve, reject) => {
resolve(value)
})
}
static reject(reason) {
return new ZPromise((resolve, reject) => {
reject(reason)
})
}
// 全部
static all(promises) {
return new ZPromise((resolve, reject) => {
let arr = [];
let i = 0;
function getResult(index, value) {
arr[index] = value;
if (++i == promises.length) {
resolve(arr)
}
}
for (let i = 0; i < promises.length; i++) {
promises[i].then(data => {
getResult(i, data)
}, reject)
}
})
}
// 第一个
static race(promises) {
return new ZPromise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
// resolve后,状态不能改变
promises[i].then(resolve, reject)
}
})
}
constructor(cb) {
this.status = PENDDING;
this.value = null; // 成功返回值
this.reason = null;// 失败返回值
this.fullfiedCbs = []; // 异步时候收集成功回调
this.rejectCbs = [];// 异步时候收集的失败回调
let resolve = value => {
// console.log("进入resolve")
// 判断当前状态,一旦决议,不允许再改变
if (this.status === PENDDING) {
this.status = FULLFILED
this.value = value
if (this.fullfiedCbs.length > 0) {
this.fullfiedCbs.forEach(cb => cb(this.value))
}
}
}
let reject = error => {
if (this.status === PENDDING) {
this.status = REJECT
this.reason = error
if (this.fullfiedCbs.length > 0) {
this.rejectCbs.forEach(cb => cb(this.reason))
}
}
}
cb(resolve, reject)
}
catch(onrejected) {
return this.then(null, onrejected)
}
then(onfullfied, onrejected) {
// console.log('进入then')
onfullfied = typeof onfullfied === 'function' ? onfullfied : (value => value)
onrejected = typeof onrejected === 'function' ? onrejected : error => { throw error }
// 返回一个promise1
let promise1 = new ZPromise((resolve, reject) => {
resolveTask = resolveTask.bind(this)
// 判断状态 决议
if (this.status === FULLFILED) {
// console.log('进立即resolve')
setTimeout(() => resolveTask(onfullfied, resolve, reject), 0)
}
if (this.status === REJECT) {
// console.log('进立即reject')
setTimeout(() => resolveTask(onrejected, resolve, reject), 0)
}
// 1.若promise立即决议,则会直接调用上面的分支
//2. 若promise resolve或者reject中有异步任务,则执行then方法时,还处于挂起状态,只需要先将回调函数暂存,等待resolve后调用
if (this.status === PENDDING) {
// console.log('进pedding')
this.fullfiedCbs.push(() => setTimeout(() => resolveTask(onfullfied, resolve, reject), 0))
this.rejectCbs.push(() => setTimeout(() => resolveTask(onrejected, resolve, reject), 0))
}
})
// 执行回调
function resolveTask(fn, resolve, reject) {
try {
let ret = fn(this.value)
resolvePromise(promise1, ret, resolve, reject)
} catch (err) {
reject(err)
}
}
return promise1
}
}
测试基础功能
const p1 = new ZPromise((resolve, reject) => {
resolve(1);
});
p1.then(val=>{
console.log('p1的then', val)
return {
name: 1
}
})
const p2 = new ZPromise((resolve, reject) => {
setTimeout(() => {
resolve(2);
}, 1000)
});
p2.then(val => {
console.log("p2的then", val)
return new ZPromise(resolve => {
console.log("返回值是promise")
return resolve({
name: 1
})
})
}).then(val => {
console.log("p2的第二个then", val)
})
测试静态函数
const p1 = new ZPromise((resolve, reject) => {
resolve(1);
});
const p2 = new ZPromise((resolve, reject) => {
setTimeout(() => {
resolve(2)
}, 1000)
});
const p3 = new ZPromise((resolve, reject) => {
setTimeout(() => {
resolve(3);
}, 3000)
});
ZPromise.race([p1, p2, p3]).then(data => {
console.log(data); // 1
}, err => {
console.log(err);
});
ZPromise.all([p2, p1, p3]).then(data => {
console.log(data); // [2,1,3] 结果顺序和promise实例数组顺序是一致的
}, err => {
console.log(err);
});