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的长度 是否为0while (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;
