1.proomise 就是一个类,在执行这个类的时候 需要传递一个执行器进去, 执行器会立即执行
2.Promise 中有三种状态, 分别是 成功/fulfilled 失败/rejected 等待/pending
pending -> fulfilled
pending -> rejected
3.resolve 和 reject 函数是用来更改状态的
resolve: fulfilled
reject: rejected
4.then 方法内部做的事情就是判断状态,如果状态是成功,调用成功后的回调函数,如果状态是失败,调用失败后的回调函数, then 方法是定义在 原型上的
5.then方法成功回调有一个参数,表示成功后的值。then失败后回调有一个参数,表示失败后的原因
//实现
const PENDING = 'pending'; //等待
const FULFILLED = 'fulfilled'; //成功
const REJECTED = 'rejected'; //失败
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject)
}
status = PENDING;
value = undefined;
reason = undefined;
resolve = value => {
//判断状态是否是等待转变的 (状态一旦更改就不可改变)
if (this.status !== PENDING) return;
//将状态更改为成功
this.status = FULFILLED;
this.value = value;
}
reject = reason => {
//判断状态是否是等待转变的 (状态一旦更改就不可改变)
if (this.status !== PENDING) return;
//将状态更改为失败
this.status = REJECTED;
this.reason = reason;
}
then(successCallback, failCallback) {
if (this.status === FULFILLED) {
successCallback(this.value);
} else if (this.status === REJECTED) {
failCallback(this.reason);
}
}
}
module.exports = MyPromise
打印实验:
const MyPromise = require('./MyPromise')
let promise = new MyPromise((reasolve, reject) => {
reasolve('成功');
})
promise.then(value => {
console.log(value);
}, reason => {
console.log(reason);
})
//console.log('成功');
二、在promise中加入异步逻辑
现在的调用如果加上异步 不会执行
const MyPromise = require('./MyPromise')
let promise = new MyPromise((reasolve, reject) => {
setTimeout(() => {
reasolve('成功');
})
})
promise.then(value => {
console.log(value);
}, reason => {
console.log(reason);
})
promise.then(value => {
console.log(value);
}, reason => {
console.log(reason);
})
promise.then(value => {
console.log(value);
}, reason => {
console.log(reason);
})
//console.log('成功');
具体实现 拆分代码 待补充
完整实现代码
//实现
/*
尽可能还原 Promise 中的每一个 API, 并通过注释的方式描述思路和原理.
*/
// 状态
const PENDING = 'pending'; //等待
const FULFILLED = 'fulfilled'; //成功
const REJECTED = 'rejected'; //失败
// promise状态改变 就不会再更改 并且只能从等待转换状态
// 等待 => 成功
// 等待 => 失败
class MyPromise {
// promise会传入一个生成器 接受成功和失败方法
constructor(executor) {
try {
executor(this.resolve, this.reject);
// executor(resolve.bind(this), reject.bind(this)); 当不用箭头函数时
} catch (e) {
this.reject(e)
}
}
// 用箭头函数的原因是this指向 调用resolve时是直接调用 所以会有this(window等)指向问题
// resolve和reject是用来改变 promise 的状态的
status = PENDING; //初始化状态为等待
value = undefined; //成功返回的结果
reason = undefined; //失败的原因
//保存成功和失败回调
successcallback = []; //成功回调 数组:多次调用
failcallback = []; //失败回调 数组:多次调用
resolve = value => {
// 状态更改不可改变 判断是否是从等待转换过来的
if (this.status != PENDING) return;
// 改变promise的状态为成功
this.status = FULFILLED;
// 将 成功返回的结果 存储 方便成功后的回调函数 调用
this.value = value;
// 当异步任务结束时 看successcallback的长度 是否为0
while (this.successcallback.length) this.successcallback.shift()(this.value)
}
reject = reason => {
// 状态更改不可改变 判断是否是从等待转换过来的
if (this.status != PENDING) return;
// 改变promise的状态为失败
this.status = REJECTED;
// 将 失败的原因 存储 方便成功后的回调函数 调用
this.reason = reason;
// 当异步任务结束时 failcallback 是否存在
while (this.failcallback.length) this.failcallback.shift()(this.reason)
}
// 方法 存放的是成功回调和失败回调
then(succesback, failback) {
// 将参数变为可选参数
succesback = succesback ? succesback : value => value;
failback = failback ? failback : reason => { throw reason };
// 实现then方法的链式调用 就是返回一个Promise(这样才能调用then方法)
let promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
try {
// 当状态为成功时 调用成功的回调
let hui = succesback(this.value); //保存这个then方法的 回调
// resolve(hui); //带着这个 个then的 回调
resolvePromise(hui, promise2, resolve, reject);
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
// 当状态为失败时 调用失败的回调
let hui = failback(this.reason); //保存这个then方法的 回调
// resolve(hui); //带着这个 个then的 回调
resolvePromise(hui, promise2, resolve, reject);
} catch (e) {
reject(e)
}
}, 0)
} else {
//当前是 处理异步的情况
// 当走到这里时 你无法知道一异步之后 该调用成功还是失败 所以将成功和失败 回调 保存起来先
this.successcallback.push(() => {
setTimeout(() => {
try {
// 当状态为成功时 调用成功的回调
let hui = succesback(this.value); //保存这个then方法的 回调
// resolve(hui); //带着这个 个then的 回调
resolvePromise(hui, promise2, resolve, reject);
} catch (e) {
reject(e)
}
}, 0)
});
this.failcallback.push(() => {
setTimeout(() => {
try {
// 当状态为失败时 调用失败的回调
let hui = failback(this.reason); //保存这个then方法的 回调
// resolve(hui); //带着这个 个then的 回调
resolvePromise(hui, promise2, resolve, reject);
} catch (e) {
reject(e)
}
}, 0)
});
}
})
return promise2;
}
// 失败回调
catch(failback) {
return this.then(undefined, failback)
}
// 无论结果是成功 还是失败 都会返回一个结果
finally(callback) {
return this.then(value => {
// 这里调用 resolve 静态方法
return MyPromise.resolve(callback()).then(() => value)
}, reason => {
return MyPromise.resolve(callback()).then(reason => reason)
})
}
//静态方法 允许按照异步代码调用的顺序 返回 相应结果的顺序
static all(array) {
let result = []; //结果数组
let index = 0; //判断异步是否执行完成 就是判断index 得值 是否与 result 的长度相等
return new MyPromise((resolve, reject) => {
function add(i, value) {
result[i] = value;
index++;
if (index == array.length) {
resolve(result)
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i];
if (current instanceof MyPromise) {
//是promise对象
current.then(value => add(i, value), reason => reject(reason))
} else {
//普通值
add(i, current);
}
}
})
}
//返回一个解析过的Promise对象,如果参数本身就是一个Promise对象,则直接返回这个Promise对象
static resolve(value) {
if (value instanceof MyPromise) return value;
return new MyPromise((resolve, reason) => {
resolve(value)
})
}
//返回一个解析过的Promise对象,如果参数本身就是一个Promise对象,则直接返回这个Promise对象
static reject(value) {
if (value instanceof MyPromise) return value;
return new MyPromise((resolve, reason) => {
reason(value)
})
}
}
//判断上一个返回的回调(hui) 是否是promise对象
//如果是普通值 就直接调用 resolve()
//如果是promise对象 查看promise返回的结果 调用then方法
//再根据返回的结果 调用相应的成功方法和失败方法
function resolvePromise(hui, promise2, resolve, reject) {
if (promise2 === hui) {
return reject(new TypeError('lsdhflsdb'))
}
if (hui instanceof MyPromise) {
// 判断是否是promise 对象
hui.then(resolve, reject)
} else {
// 否则是 普通值
resolve(hui)
}
}
module.exports = MyPromise;