1. 基本概念:
Promise 是异步编程的一种解决方案:
promise是一个对象,从它可以获取异步操作的消息;它是承诺,承诺它过一段时间会给你一个结果。
promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。创造promise实例后,它会立即执行
。
promise是用来解决两个问题的:
- 回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象。
- promise可以支持多个并发的请求,获取并发请求中的数据。
promise本身是同步的
。
2.代码实现
class Promise {
constructor(executor) {
this.state = 'pending'; // 初始化state为等待态.
this.value = undefined; // 成功的值
this.reason = undefined; // 失败的原因
this.onResolvedCallbacks = []; // 成功存放的数组
this.onRejectedCallbacks = []; // 失败存放数组
let resolve = value => {
if (this.state === 'pending') { // state改变,resolve调用就会失败
this.state = 'fulfilled'; // resolve调用后,state转化为成功态
this.value = value; // 储存成功的值
this.onResolvedCallbacks.forEach(fn => fn()); // 一旦resolve执行,调用成功数组的函数
}
}
let reject = reason => {
if (this.state === 'pending') { // state改变,reject调用就会失败
this.state = 'rejected'; // reject调用后,state转化为失败态
this.reason = reason; // 储存失败的原因
this.onRejectedCallbacks.forEach(fn => fn()); // 一旦reject执行,调用失败数组的函数
}
}
// 如果executor执行报错,直接执行reject
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
then(onFulfilled, onRejected) {
// onFulfilled如果不是函数,就忽略onFulfilled,直接返回value
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
// onRejected如果不是函数,就忽略onRejected,直接扔出错误
onRejected = typeof onRejected === 'function' ? onRejected : err => {throw err};
// 声明返回的promise2
let promise2 = new Promise((resolve, reject)=> {
// 状态为fulfilled,执行onFulfilled,传入成功的值
if (this.state === 'fulfilled') {
// 异步
setTimeout(()=> {
try {
let x = onFulfilled(this.value);
// resolvePromise函数,处理自己return的promise和默认的promise2的关系
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e)
}
}, 0)
}
// 状态为rejected,执行onRejected,传入失败的原因
if (this.state === 'rejected') {
// 如果报错
setTimeout(()=> {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e)
}
}, 0)
}
// 当状态state为pending时
if (this.state === 'pending') {
// onFulfilled传入到成功数组
this.onResolvedCallbacks.push(()=> {
setTimeout(()=> {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0)
})
// onRejected传入到失败数组
this.onRejectedCallbacks.push(()=> {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e)
}
}, 0)
})
}
});
// 返回promise,完成链式
return promise2;
}
catch(onRejected) {
return this.then(undefined, onRejected)
}
static resolve (val) {
return new Promise((resolve, reject) => {
resolve(val)
})
}
static reject (val) {
return new Promise((resolve, reject) => {
reject(val)
})
}
// 只要有一个promise成功了 就算成功。如果第一个失败了就失败了
static race (promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(resolve, reject)
}
})
}
//all方法(获取所有的promise,都执行then,把结果放到数组,一起返回)
static all(promises) {
let arr = [];
let count = 0;
return new Promise((resolve, reject)=> {
function processData(index, data) {
arr[index] = data;
count ++;
if (count === promises.length) {
resolve(arr)
}
}
for (let i = 0; i < promises.length; i++) {
promises[i].then(data=> {
processData(i, data)
}, reject)
}
})
}
}
function resolvePromise(promise2, x, resolve, reject){
// 循环引用报错
if (x === promise2) {
return reject(new TypeError('循环引用'));
}
// 防止多次调用
let isCalled = false;
// x不是null 且x是对象或者函数
if (x != null && (typeof x === 'object' || typeof x === 'function')) {
try {
// A+规定,声明then = x的then方法
let then = x.then;
// 如果then是函数,就默认是promise了
if (typeof then === 'function') {
// 就让then执行 第一个参数是this 后面是成功的回调 和 失败的回调
then.call(x, y=> {
// 成功和失败只能调用一个
if (isCalled) return
isCalled = true;
// resolve的结果依旧是promise 那就继续解析
resolvePromise(promise2, y, resolve, reject)
}, err => {
if (isCalled) return
isCalled = true;
reject(err); // 失败了就失败了
})
} else {
resolve(x); // 直接成功即可
}
} catch (e) {
if (isCalled) return
isCalled = true;
reject(e); // 取then出错了那就不要在继续执行了
}
} else { // 否则x是普通的值,直接resolve
resolve(x)
}
}