苏州定制型网站建设,做网站那家比较好,课件模板下载免费,合伙做网站怎么分配股权promise
在开发中#xff0c;经常需要用到promise#xff0c;promise具有很多特性#xff0c;这一次将对promise特性进行总结#xff0c;并从零写一个promise。
步骤一
Promise特点 1#xff0c;创建时需要传递一个函数#xff0c;否则会报错2#xff0c;会给传入的函…promise
在开发中经常需要用到promisepromise具有很多特性这一次将对promise特性进行总结并从零写一个promise。
步骤一
Promise特点 1创建时需要传递一个函数否则会报错2会给传入的函数设置两个回调函数3刚创建的Promise对象状态是pending
class MyPromise {constructor(handle) {// 3刚创建的Promise对象状态是pendingthis.status pending;// 1创建时需要传递一个函数否则会报错if (!this._isFunction(handle)) {throw new Error(请传入一个函数);}// 2会给传入的函数设置两个回调函数handle(this._resolve.bind(this), this._reject.bind(this))}_resolve() {}_reject() {}_isFunction(fn) {return typeof fn function;}
}步骤二
Promise特点 4状态一旦发生改变就不可再次改变5可以通过then来监听状态的改变 5.1如果创建监听时状态已经改变立即执行监听回调5.2如果创建监听时状态未改变会等状态改变后执行5.3同一promise对象可以添加多个then监听状态改变时按照注册顺序依次执行
// 定义常量保存对象的状态
const PENDING pending;
const FULFILLED fulfilled;
const REJECTED rejected;class MyPromise {constructor(handle) {// 3刚创建的Promise对象状态是pendingthis.status PENDING;// 成功回调的值this.value undefined;// 失败回调的值this.reason undefined;// 注册的成功回调this.onResolvedCallbacks [];// 注册的失败回调this.onRejectedCallbacks [];// 1创建时需要传递一个函数否则会报错if (!this._isFunction(handle)) {throw new Error(请传入一个函数);}// 2会给传入的函数设置两个回调函数handle(this._resolve.bind(this), this._reject.bind(this))}_resolve(value) {// 4状态一旦发生改变就不可再次改变if (this.status PENDING) {this.status FULFILLED;this.value value;// 5.3同一promise对象可以添加多个then监听状态改变时按照注册顺序依次执行this.onResolvedCallbacks.forEach(fn fn(this.value));}}_reject(reason) {// 4状态一旦发生改变就不可再次改变if (this.status PENDING) {this.status REJECTED;this.reason reason;// 5.3同一promise对象可以添加多个then监听状态改变时按照注册顺序依次执行this.onRejectedCallbacks.forEach(fn fn(this.reason));}}then(onResolved, onRejected) {// 判断有没有传入成功的回调if (this._isFunction(onResolved)) {// 5.1如果创建监听时状态已经改变立即执行监听回调if (this.status FULFILLED) {onResolved(this.value);}}// 判断有没有传入失败的回调if (this._isFunction(onRejected)) {// 5.1如果创建监听时状态已经改变立即执行监听回调if (this.status REJECTED) {onRejected(this.reason);}}// 5.2如果创建监听时状态未改变会等状态改变后执行if (this.status PENDING) {if (this._isFunction(onResolved)) {this.onResolvedCallbacks.push(onResolved);}if (this._isFunction(onRejected)) {this.onRejectedCallbacks.push(onRejected);}}}_isFunction(fn) {return typeof fn function;}
}详解then方法
接收两个参数成功回调失败回调如果promise失败了但是没有注册失败监听就会报错then方法每次执行完毕都会返回一个新的Promise对象 如果then方法只有成功回调 则它返回的promise的状态会继承当前promise的状态。如果当前promise的状态为成功新promise的值为当前then的成功回调的返回值。如果当前promise的状态为失败新的promise没有失败监听则会报错 如果then方法同时包含成功回调、失败回调则它返回的promise的状态都为成功且值为成功或者失败回调的返回值。 回调函数的返回值 如果then方法的成功/失败回调返回的是promise对象 则then方法返回的新的promise对象的状态由新promise的内部决定。且值为新promise的内resolve/reject函数传递的参数。 如果then方法的成功/失败回调返回的是普通数据类型 则then方法返回的新的promise对象的状态都为成功。且值为成功/失败回调的返回值即都会传递给新的promise对象成功的回调。 如果then方法的成功/失败回调没有返回值 同返回普通数据类型 失败回调函数 可以捕获上一个promise对象的then方法中成功回调函数执行时的异常
参考 前端进阶面试题详细解答
then(onResolved, onRejected) {return new MyPromise((nextResolve, nextReject) {// 1.判断有没有传入成功的回调if (this._isFunction(onResolved)) {// 2.判断当前的状态是否是成功状态if (this.status FULFILLED) {try {// 拿到上一个promise成功回调执行的结果let result onResolved(this.value);// console.log(result, result);// 判断执行的结果是否是一个promise对象if (result instanceof MyPromise) {result.then(nextResolve, nextReject);} else {// 将上一个promise成功回调执行的结果传递给下一个promise成功的回调nextResolve(result);}} catch (e) {nextReject(e);}}}// 1.判断有没有传入失败的回调// if(this._isFunction(onRejected)){try {// 2.判断当前的状态是否是失败状态if (this.status REJECTED) {let result onRejected(this.reason);if (result instanceof MyPromise) {result.then(nextResolve, nextReject);} else {nextResolve(result);}}} catch (e) {nextReject(e);}// }// 2.判断当前的状态是否是默认状态if (this.status PENDING) {if (this._isFunction(onResolved)) {// this.onResolvedCallback onResolved;this.onResolvedCallbacks.push(() {try {let result onResolved(this.value);if (result instanceof MyPromise) {result.then(nextResolve, nextReject);} else {nextResolve(result);}} catch (e) {nextReject(e);}});}// if(this._isFunction(onRejected)){// this.onRejectedCallback onRejected;this.onRejectedCallbacks.push(() {try {let result onRejected(this.reason);if (result instanceof MyPromise) {result.then(nextResolve, nextReject);} else {nextResolve(result);nextReject();}} catch (e) {nextReject(e);}});// }}});
}详解catch方法
其实是then方法的失败回调函数的语法糖如果需要同时使用then和catch方法必须使用链式编程不然会报错可以捕获上一个promise对象的then方法中成功回调函数执行时的异常
catch(onRejected) {return this.then(undefined, onRejected);
}为啥使用catch时最好使用链式编程
因为then方法只有成功回调所以p2的状态会继承p1又因为p2的状态为失败且没有对p2进行失败监听所以报错
let p1 new Promise(function (resolve, reject) {// resolve();reject();
});
let p2 p1.then(function () {console.log(成功);
});
p1.catch(function () {console.log(失败1);
});Promise.all()
Promise.all(params)特点 参数为一个数组且数组元素为promise类型数据返回值为一个promise 如果所有promise都执行成功 返回值为所有promise都成功时返回的结果的集合 如果有一个promise执行失败了则返回失败的promise
static all(list){return new MyPromise(function (resolve, reject) {let arr [];let count 0;for(let i 0; i list.length; i){let p list[i];p.then(function (value) {// arr.push(value); 注意不要这样写会导致结果顺序不对arr[i] valuecount;if(list.length count){resolve(arr);}}).catch(function (e) {reject(e);});}});
}Promise.race()
Promise.race(params)特点 参数为一个数组且数组元素为promise类型数据返回值为一个promise且返回值为第一个成功或者失败的promise的值
static race(list){return new MyPromise(function (resolve, reject) {for(let p of list){p.then(function (value) {resolve(value);}).catch(function (e) {reject(e);});}})
}