// 给实例对象的身上添加属性,直接通过this强行复制的方式去添加,这里的this就指的是新创建(new出来的)的实例对象 this.PromiseState = "pending"; this.PromiseResult = null; // 声明属性用来保存then方法中的回调函数 this.callBacks = [];
// 解决下方this指向问题,可以在这里先把this的指向保存下来 const that = this; // const _this = this; // const self = this; //三种保存this值的常见写法 function resolve(data) { // 判断Promise实例对象的状态(状态变为成功或者失败就不能再次改动) if (that.PromiseState !== "pending") return; // 1.修改对象的状态(PromiseState) // 注意:这里的this指向的不是新new出来实例对象,而是指向全局的Window对象(所以要提前把this的值保存下来) that.PromiseState = "fulfilled"; //或者为resolve(意思都一样) // 2.修改对象结果值(PromiseResult) that.PromiseResult = data; // 调用成功的回调函数 that.callBacks.forEach((item) => { setTimeout(() => { //加定时器让回调函数变为异步操作 item.onResolved(data); //forEach不会遍历数组元素为empty(空)的数组,所以加不加判断条件都不会影响性能 }); }); } // reject函数---里面还需要声明形参去接收实参 function reject(data) { // 判断Promise实例对象的状态(状态变为成功或者失败就不能再次改动) if (that.PromiseState !== "pending") return; // 1.修改对象的状态(PromiseState) that.PromiseState = "rejected"; // 2.修改对象结果值(PromiseResult) that.PromiseResult = data; // 调用失败的回调函数 that.callBacks.forEach((item) => { setTimeout(() => { item.onRejected(data); }); }); }
// 同步调用(执行器函数-executor) try { executor(resolve, reject); } catch (error) { // 修改Promise实例对象的状态为失败 reject(error); } }
// then方法的封装 then(onResolved, onRejected) { const that = this;
// 判断回调函数参数是否传递的是一个函数,如果不是一个函数,就给他添加一个默认值---值为函数 if (typeof onResolved !== "function") { onResolved = (value) => value; //value=>{return value} ES6 }
if (typeof onRejected !== "function") { onRejected = (reason) => { throw reason; }; } return new Promise((resolve, reject) => { // 封装函数 function callBack(type) { try { // 在这里还有传入实参,实参为Promise实例对象成功之后的结果值 // 获取成功函数的执行结果 let result = type(that.PromiseResult); //this指向有问题,在函数内部直接调用,指的是Window
// 判断result是不是Promise的实例对象 if (result instanceof Promise) { // 如果是Promise类型的对象 result.then( (v) => { resolve(v); }, (r) => { reject(r); } ); } else { // 结果的对象状态为成功 resolve(result); } } catch (error) { reject(error); } }
// 调用回调函数并且加上判断条件(判断Promise实例对象身上的PromiseState属性) // 这里的this指的是Promise实例对象(函数包裹第一层的时候里面的this指向的是实例对象,第二层指向的是Window,除非第二层写箭头函数,箭头函数没有自己的this,所以this指向的就是外部的定义时的this,就是Promise实例对象),标准说法为构造函数中的this,后期谁调用指谁 if (this.PromiseState === "fulfilled") { setTimeout(() => { //加定时器更改回调函数为异步执行 callBack(onResolved); }); }
if (this.PromiseState === "rejected") { setTimeout(() => { callBack(onRejected); }); }
// 判断pending状态 if (this.PromiseState === "pending") { // 保存回调函数 this.callBacks.push({ // ES6简写 // onResolved, //相当于onResolved:onResolved // onRejected, //相当于onRejected:onRejected
onResolved: function () { callBack(onResolved); }, onRejected: function () { callBack(onRejected); }, }); } }); }
// catch方法的封装 catch(onRejected) { return this.then(undefined, onRejected); }
// resolve方法的封装 static resolve(value) { return new Promise((resolve, reject) => { if (value instanceof Promise) { value.then( (v) => { resolve(v); }, (r) => { reject(r); } ); } else { resolve(value); } }); }
// reject方法的封装 static reject(reason) { return new Promise((resolve, reject) => { reject(reason); }); }
// all方法的封装 static all(promises) { // 声明一个变量,用来判断promises数组里的Promise对象状态十分都为成功 let count = 0; // 声明一个变量,用来保存成功的结果,结果是一个数组 let arr = [];
// 结果为Promise的对象 return new Promise((resolve, reject) => { // 遍历---这里的变量i必须使用let声明,不然i会被全局污染 for (let i = 0; i < promises.length; i++) { // parmises[i]是其中的一个Promise对象 promises[i].then( (v) => { // 得知对象的状态是成功的 // 如果每一个Promise对象的状态都是成功的,才能去执行resolve函数 count++; // 将当前Promise对象的结果存入到数组中 // arr.push(v);这种方法保存结果有点bug,异步的时候会导致顺序跟数组里面传进来Promise对象顺序不一致 arr[i] = v; // 判断:如果count的值等于promises数组的长度,就说明这个promises数组里的Promise数组状态都为成功 if (count === promises.length) { // 修改状态 resolve(arr); } }, (r) => { reject(r); } ); } }); }
// race方法的封装 static race(promises) { return new Promise((resolve, reject) => { for (let i = 0; i < promises.length; i++) { promises[i].then( (v) => { // 修改返回对象的状态为成功 resolve(v); }, (r) => { // 修改返回对象的状态为失败 reject(r); } ); } }); } }