一、catch方法的实现
catch方法是用来捕获一个失败的Promise对象,然后在返回一个失败的Promise对象
代码:
//直接调用then方法来返回一个失败结果 Promise.prototype.catch = function(onRejected) { return this.then(undefined, onRejected); }
测试:
<script> let p = new Promise((resolve, reject) => { reject('err'); // resolve('ok'); }) p.catch((reason) => { console.warn(reason) }) console.log(p) //当返回一个失败Promise时,如果不被catch,则会报错 </script>
二、异常穿透与值传递
代码:
Promise.prototype.then = function(onResolved, onRejected) { //只写了新需求的代码,之前重复的就没写了 return new Promise((resolve, reject) => { //实现异常穿透时,通常会省略onRejected回调函数,所以我们需要在底层实现该逻辑 if (typeof onRejected !== 'function') { onRejected = rea => { throw rea // throw会返回一个失败的Promise /* 如果返回的一个成功的Promise或者非Promise类型,则不会被cathch捕获到 如:return rea console.log(rea) */ } } //实现值传递时,可能会省略onResolved回调函数,所以我们需要在底层实现该逻辑 if (typeof onResolved !== 'function') { onResolved = val => { return val; } } } }
测试:
<script> let p = new Promise((resolve, reject) => { reject('err'); // resolve('ok'); }) //异常穿透,只要有一个出错,就被捕获到catch中去 p.then(value => { console.log(111); }).then(value => { console.log(222); }).then(value => { console.log(333); }).catch(reason => { console.warn(reason) }) //值传递,对应需要成功回调 p.then() .then(value => { console.log(222); }).then(value => { console.log(333); }) console.log(p) </script>
三、resolve方法的实现
该方法是Promise构造函数身上的一个方法,且返回对象和then方法是一样的
1.如果回调函数结果是一个非Promise对象,则返回一个成功的Promise
2.如果回调函数结果是一个Promise对象,则返回结果由该Promise对象决定
代码:
//所以该代码实现逻辑和then方法中类似 Promise.resolve = function(value) { return new Promise((resolve, reject) => { if (value instanceof Promise) { value.then(val => { resolve(val); }, rea => { reject(rea); }) } else { resolve(value); } }); }
测试:
<script> let p1 = Promise.resolve('ok'); let p2 = Promise.resolve(new Promise((resolve, reject) => { resolve('okkk'); })); let p3 = Promise.resolve(new Promise((resolve, reject) => { reject('err'); })); console.log(p1,p2,p3); </script>
四、reject方法的实现
该方法总是返回一个失败的Promise
代码:
Promise.reject = function(reason) { return new Promise(reject => { reject(reason); }) }
测试:
<script> let p1 = Promise.reject('err'); let p2 = Promise.reject(new Promise(resolve,reject) => { resolve('ok'); }) console.log(p1,p2); </script>
五、all方法的实现
该方法接收一个promise数组,只有当这个数组中的所有promise成功时,才返回成功的Promise对象,但如果有一个失败,则返回其失败的Promis
代码:
Promise.all = function(promises) { let count = 0; //来计算数组中成功promise的数量 let arr = []; return new Promise((resolve, reject) => { for (let i = 0; i < promises.length; i++) { promises[i].then(val => { count++; arr[i] = val; //此处不能使用数组的push()方法,因为当Promise中有异步执行时,会打乱顺序(如下测试中的p2,如果使用的是push方法,则会先将p3的结果存入数组,后将p2的结果存入) if (count === promises.length) resolve(arr); }, rea => { reject(rea); }); } }); }
测试:
<script> let p1 = Promise.resolve('ok'); let p2 = Promise.resolve(new Promise((resolve, reject) => { // resolve('okkk'); setTimeout(() => { resolve('okkk'); }, 1000) })); let p3 = Promise.resolve(new Promise((resolve, reject) => { reject('err'); // resolve('lkd'); })); const promises = [p1, p2, p3]; let ps = Promise.all(promises) console.log(ps) </script>
六、race方法的实现
该方法也需要传入一个promise数组,但它只要有一个先成功或者先失败,就返回其Promise结果
代码:
Promise.race = function(promises) { return new Promise((resolve, reject) => { for (let i = 0; i < promises.length; i++) { promises[i].then(val => { resolve(val); }, rea => { reject(rea); }); } }); }
测试:
<script> // let p1 = Promise.resolve('ok'); let p2 = Promise.resolve(new Promise((resolve, reject) => { // reject('err'); setTimeout(()=>{ resolve('lkd'); },1000) })); let p3 = Promise.reject('error'); // const promises = [p1, p2, p3]; const promises = [p2,p3] let pn = Promise.race(promises) console.log(pn) </script>
七、实现then回调的异步执行
代码:
function Promise(executor) { function resolve(data) { setTimeout(() => { self.callback.forEach(item => { item.onResolved(data) }) }) } function reject(data) { setTimeout(() => { self.callback.forEach(item => { item.onRejected(data) }) }) } Promise.prototype.then = function(onResolved, onRejected) { return new Promise((resolve, reject) => { if (this.PromiseState === 'fulfilled') { setTimeout(() => { callback(onResolved) }) } if (this.PromiseState === 'rejected') { setTimeout(() => { callback(onRejected) }) } }) }
测试:
<script> let p = new Promise((resolve, reject) => { resolve('ok'); console.log('111'); }) p.then(val=>{ console.log('222'); }) console.log('333'); /* 此测试如果没有实现then回调的异步执行,则会输出: 111 222 333 */ </script>