🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
1.在 new Promise的时候接受一个方法,方法中有resolve和reject两个方法,分别对应promise状态改变时的操作 2.promise对象内部存在三种状态,分别是 pending, fulfilled, rejected,promise 3.对象在创建的时候,会立即执行其中传入的方法,并且通过resolve和reject方法改变status 4.当 promise.then执行的时候,会传入onFulfilled和onRejected方法,这时候会检查promise内部状态,这里存在三种情况: 一个是pending的时候,说明状态没有改变有可能是resolve方法被异步加载,那么会被把传入的onFulfilled和onRejected方法push到resolveCallbacks和rejectCallbacks队列当中; 第二种是fulfilled状态,说明被resolve了,那么就会执行当前的onFulfilled方法 第三种就是rejected状态,说明被reject了,那么就会执行当前的onRejected方法 5.如果resolve或者reject被异步了,那么就会先通过then将传入的方法放到callbacks队列中,等到promise内部resolve或者reject方法执行时,清空callbacks上的方法 6.promise返回的是一个promise对象,promise对象.then返回的仍然是一个promise对象 ```js /** * promise 状态: * pendding: 初始状态 pendding 可以转为 fulfilled和 rejected * fulfilled * rejected */ class Commitment { static PENDING = "待定"; static FULFILLED = "成功"; static REJECTED = "拒绝"; constructor(func) { this.status = Commitment.PENDING; // 一开始为 pendding this.result = null; // 结果 this.resolveCallbacks = []; this.rejectCallbacks = []; // 这里需要bind this,否则new实例过程中立即调用func函数,此时还没有this // func(this.resolve.bind(this), this.reject.bind(this)) // 传入后立即执行 try { func(this.resolve.bind(this), this.reject.bind(this)); } catch (error) { // 如果报错,直接执行 reject this.reject(error); } } // resole和reject是在创建 promise 的过程中调用的 resolve(result) { // result 为 new Promise 时 resolve(result)中的result setTimeout(() => { // resolve 时,如果状态为 pendding,则改为 fulfilled if (this.status === Commitment.PENDING) { this.status = Commitment.FULFILLED; this.result = result; // 如果是异步,resolve可能会比 then 后执行 // 检查 callbacks数组并执行 this.resolveCallbacks.forEach((callback) => { callback(result); }); } }); } reject(result) { // reject 的时候,如果状态为 pendding,则改为 rejected setTimeout(() => { if (this.status === Commitment.PENDING) { this.status = Commitment.REJECTED; this.result = result; this.rejectCallbacks.forEach((callback) => { callback(result); }); } }); } // then 有两个参数, // onfulfilled:状态成功时,执行的回调 // onrejected: 状态为拒绝时,执行的回调 then(onFULFILLED, onREJECTED) { return new Commitment((resolve, reject) => { // 判断传入的是否是函数 if (typeof onFULFILLED !== "function") { onFULFILLED = () => {}; } if (typeof onREJECTED !== "function") { onREJECTED = () => {}; } // 如果是 pendding,说明resolve被异步了, // 把 then 应该执行的方法放到 resolveCallbacks中 if (this.status === Commitment.PENDING) { this.resolveCallbacks.push(onFULFILLED); this.rejectCallbacks.push(onREJECTED); } // 如果promise实例执行的是 resolve,则 if (this.status === Commitment.FULFILLED) { setTimeout(() => { onFULFILLED(this.result); }); } // 如果promise实例执行的是 reject,则 if (this.status === Commitment.REJECTED) { setTimeout(() => { onREJECTED(this.result); }); } }); } } let commitment = new Commitment((resolve, reject) => { // resolve实际做了两件事 // 1.把 promise实例内部的 pedding状态改为 fulfilled // 2.把 resolve(参数)的参数传入了promise实例,作为result resolve("resolve的结果"); // 这里会立即执行 resolve方法 // reject() // throw new Error('报错') }); // commitment.then( // undefined, // res => { // console.log('reject的时候会触发', res); // } // ) console.log("1"); let commitment2 = new Commitment((resolve, reject) => { // func 会立即执行 console.log("2"); setTimeout(() => { resolve("3"); // 把 resolve 的内容存在 result 中了 reject("4"); console.log(5); }); }); commitment2.then( (result) => { console.log(result, "6"); }, (result) => { console.log(result, "7"); } ); console.log("8"); ```