前提
promise 是一个代理,它代表一个在创建 promise 时不一定已知的值。
它允许你将处理程序与异步操作的最终成功值或失败原因关联起来。
这使得异步方法可以像同步方法一样返回值:异步方法不会立即返回最终值,而是返回一个 promise,以便在将来的某个时间点提供该值。
简要概述:promise是一个允许你使用异步操作的代理
promise 状态
待定(pending):初始状态,既没有被兑现,也没有被拒绝。
已兑现 (fulfiled):意味着操作成功完成。
已拒绝 (rejected):意味着操作失败。
// 微任务
// 根据mdn,为了能够使得第三方库、polyfill等能够执行微任务,JS环境(浏览器和Node)暴露了全局的queueMicroTask接口
queueMicroTask(()=>{ const name="task" console.log(name)
})
Promise A+规范
// 第一步 构造器 接受一个函数参数
// 这个函数的两个参数 执行Promise中的resolve, reject方法 改变 当前Promise的状态
class Promise{// 构造器constructor(executor){// 成功let resolve = () => { };// 失败let reject = () => { };// 立即执行executor(resolve, reject);}
}
// 第二步 Promise的状态 和值
class Promise{constructor(executor){// 初始化state为等待态this.state = 'pending';// 成功的值this.value = undefined;// 失败的原因this.reason = undefined;let resolve = value => {// state改变,resolve调用就会失败if (this.state === 'pending') {// resolve调用后,state转化为成功态this.state = 'fulfilled';// 储存成功的值this.value = value;}};let reject = reason => {// state改变,reject调用就会失败if (this.state === 'pending') {// reject调用后,state转化为失败态this.state = 'rejected';// 储存失败的原因this.reason = reason;}};// 如果executor执行报错,直接执行rejecttry{executor(resolve, reject);} catch (err) {reject(err);}}
}
第三步 Promise.then方法 该方法接受两个参数 onFulfilled onRejected
class Promise{constructor(executor){...}// then 方法 有两个参数onFulfilled onRejectedthen(onFulfilled,onRejected) {// 状态为fulfilled,执行onFulfilled,传入成功的值if (this.state === 'fulfilled') {onFulfilled(this.value);};// 状态为rejected,执行onRejected,传入失败的原因if (this.state === 'rejected') {onRejected(this.reason);};}
}
第四步 考虑链式调用 及 resolvePromise
class Promise{constructor(executor){this.state = 'pending';this.value = undefined;this.reason = undefined;this.onResolvedCallbacks = [];this.onRejectedCallbacks = [];let resolve = value => {if (this.state === 'pending') {this.state = 'fulfilled';this.value = value;this.onResolvedCallbacks.forEach(fn=>fn());}};let reject = reason => {if (this.state === 'pending') {this.state = 'rejected';this.reason = reason;this.onRejectedCallbacks.forEach(fn=>fn());}};try{executor(resolve, reject);} catch (err) {reject(err);}}then(onFulfilled,onRejected) {// 声明返回的promise2let promise2 = new Promise((resolve, reject)=>{if (this.state === 'fulfilled') {let x = onFulfilled(this.value);// resolvePromise函数,处理自己return的promise和默认的promise2的关系resolvePromise(promise2, x, resolve, reject);};if (this.state === 'rejected') {let x = onRejected(this.reason);resolvePromise(promise2, x, resolve, reject);};if (this.state === 'pending') {this.onResolvedCallbacks.push(()=>{let x = onFulfilled(this.value);resolvePromise(promise2, x, resolve, reject);})this.onRejectedCallbacks.push(()=>{let x = onRejected(this.reason);resolvePromise(promise2, x, resolve, reject);})}});// 返回promise,完成链式return promise2;}
}
代码合集
class Promise{constructor(executor){this.state = 'pending';this.value = undefined;this.reason = undefined;this.onResolvedCallbacks = [];this.onRejectedCallbacks = [];let resolve = value => {if (this.state === 'pending') {this.state = 'fulfilled';this.value = value;this.onResolvedCallbacks.forEach(fn=>fn());}};let reject = reason => {if (this.state === 'pending') {this.state = 'rejected';this.reason = reason;this.onRejectedCallbacks.forEach(fn=>fn());}};try{executor(resolve, reject);} catch (err) {reject(err);}}then(onFulfilled,onRejected) {onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err };let promise2 = new Promise((resolve, reject) => {if (this.state === 'fulfilled') {setTimeout(() => {try {let x = onFulfilled(this.value);resolvePromise(promise2, x, resolve, reject);} catch (e) {reject(e);}}, 0);};if (this.state === 'rejected') {setTimeout(() => {try {let x = onRejected(this.reason);resolvePromise(promise2, x, resolve, reject);} catch (e) {reject(e);}}, 0);};if (this.state === 'pending') {this.onResolvedCallbacks.push(() => {setTimeout(() => {try {let x = onFulfilled(this.value);resolvePromise(promise2, x, resolve, reject);} catch (e) {reject(e);}}, 0);});this.onRejectedCallbacks.push(() => {setTimeout(() => {try {let x = onRejected(this.reason);resolvePromise(promise2, x, resolve, reject);} catch (e) {reject(e);}}, 0)});};});return promise2;}catch(fn){return this.then(null,fn);}
}
function resolvePromise(promise2, x, resolve, reject){if(x === promise2){return reject(new TypeError('Chaining cycle detected for promise'));}let called;if (x != null && (typeof x === 'object' || typeof x === 'function')) {try {let then = x.then;if (typeof then === 'function') { then.call(x, y => {if(called)return;called = true;resolvePromise(promise2, y, resolve, reject);}, err => {if(called)return;called = true;reject(err);})} else {resolve(x);}} catch (e) {if(called)return;called = true;reject(e); }} else {resolve(x);}
}
//resolve方法
Promise.resolve = function(val){return new Promise((resolve,reject)=>{resolve(val)});
}
//reject方法
Promise.reject = function(val){return new Promise((resolve,reject)=>{reject(val)});
}
//race方法
Promise.race = function(promises){return new Promise((resolve,reject)=>{for(let i=0;i<promises.length;i++){promises[i].then(resolve,reject)};})
}
//all方法(获取所有的promise,都执行then,把结果放到数组,一起返回)
Promise.all = function(promises){let arr = [];let i = 0;function processData(index,data){arr[index] = data;i++;if(i == promises.length){resolve(arr);};};return new Promise((resolve,reject)=>{for(let i=0;i<promises.length;i++){promises[i].then(data=>{processData(i,data);},reject);};});
}
如何验证我们的promise是否正确
1、先在后面加上下述代码
2、npm 有一个promises-aplus-tests插件 npm i promises-aplus-tests -g 可以全局安装 mac用户最前面加上sudo
3、命令行 promises-aplus-tests [js文件名] 即可验证