一、resolve与reject代码实现
建议:在看懂后自己多敲两遍,并配合一定例子来进行测试(此笔记的用例均没给出结果,可以和原生Promise的结果进行比对)
代码:
function Promise(executor) { //executor:执行器函数,即同步执行函数 //给Promise构造函数身上添加两个固定的属性 this.PromiseState = 'pending'; this.PromiseResult = null; const self = this; //将self指向Promise function resolve(data) { //console.log(this),函数内的this指向的是window self.PromiseState = 'fulfilled'; self.PromiseResult = data; } /* 也可以使用箭头函数,是this指向Promise const resolve = data => { this.PromiseState = 'fulfilled'; this.PromiseResult = data; } */ function reject(data) { self.PromiseState = 'rejected'; self.PromiseResult = data; } executor(resolve, reject); }
测试:
<script> let p = new Promise((resolve, reject) => { resolve('ok'); // reject('err'); }) p.then(value => { console.log(value); }, reason => { console.warn(reason); }) console.log(p); </script>
二、接收throw抛出异常
一般throw抛出异常时,都用 try...catch...语句接收
代码:
function Promise(executor) { this.PromiseState = 'pending'; this.PromiseResult = null; const self = this ; function resolve(data) { self.PromiseState = 'fulfilled'; self.PromiseResult = data; } function reject(data) { self.PromiseState = 'rejected'; self.PromiseResult = data; } //是将函数执行的地方包含起来,而不是将所有代码都包含其中 try { executor(resolve, reject); } catch (e) { reject(e); } }
测试:
<script> let p = new Promise((resolve, reject) => { // resolve('ok'); // reject('err'); throw 'error'; }) p.then(value => { console.log(value); }, reason => { console.warn(reason); }) console.log(p); </script>
三、Promise对象只允许修改一遍
实现此功能,只需加个对Promise对象状态的判断即可
代码:
function Promise(executor) { this.PromiseState = 'pending'; this.PromiseResult = null; const self = this ; function resolve(data) { if (self.PromiseState !== 'pending') return; //此if语句使PromiseState只能修改一次 self.PromiseState = 'fulfilled'; self.PromiseResult = data; } function reject(data) { if (self.PromiseState !== 'pending') return //此if语句使PromiseState只能修改一次 self.PromiseState = 'rejected'; self.PromiseResult = data; } try { executor(resolve, reject); } catch (e) { reject(e); } }
测试:
<script> let p = new Promise((resolve, reject) => { resolve('ok'); reject('err'); }) p.then(value => { console.log(value); }, reason => { console.warn(reason); }) console.log(p); </script>
四、then方法回调的同步执行
代码:
Promise.prototype.then = function(onResolved, onRejected) { if (this.PromiseState === 'fulfilled') onResolved(this.PromiseResult) //状态为成功时,所执行的回调 if (this.PromiseState === 'rejected') onRejected(this.PromiseResult) //状态为失败时,所执行的回调 }
测试:
<script> let p = new Promise((resolve, reject) => { resolve('ok'); // reject('err'); }) p.then(value => { console.log(value); }, reason => { console.warn(reason); }) console.log(p); </script>
五、then方法回调的异步执行
此处使用定时器来实现异步
代码:
function Promise(executor) { //只写新增加的代码,前面的就不重复写了 // 添加一个对象属性,用来存储then方法中的两个回调函数 this.callback = {}; const self = this; function resolve(data) { if (self.callback.onResolved) self.callback.onResolved(data); } function reject(data) { if (self.callback.onRejected) self.callback.onRejected(data); } } Promise.prototype.then = function(onResolved, onRejected) { if (this.PromiseState === 'fulfilled') onResolved(this.PromiseResult); if (this.PromiseState === 'rejected') onRejected(this.PromiseResult); // 当Promise中是异步执行是,会先往下执行then方法,此时状态为'pending' if (this.PromiseState === 'pending') { this.callback = { onResolved, onRejected } /* 对象的简写形式,相当于: {onResolved:onResolved,onRejected,onRejected} */ }
测试:
<script> let p = new Promise((resolve, reject) => { setTimeout(()=>{ resolve('ok'); // reject('err'); },1000) }) p.then(value => { console.log(value); }, reason => { console.warn(reason); }) console.log(p); </script>
六、指定多个回调执行的实现
多个回调的执行,只需将存储的方式由对象==>数组即可
代码:
function Promise(executor) { this.callback = []; const self = this; function resolve(data) { // 当执行多个回调时使用数组形式来遍历调用 self.callback.forEach(item => { item.onResolved(data); }) function reject(data) { // 当执行多个回调时使用数组形式来遍历调用 self.callback.forEach(item => { item.onRejected(data); }) } Promise.prototype.then = function(onResolved, onRejected) { if (this.PromiseState === 'pending') { //往数组中添加只需使用push()方法即可 this.callback.push({ onResolved, onRejected }) }
测试:
<script> let p = new Promise((resolve, reject) => { resolve('ok'); // reject('err'); }) p.then(value => { console.log(value); }, reason => { console.warn(reason); }) p.then(value => { alter(value); }, reason => { console.warn(reason); }) console.log(p); </script>
七、同步修改then方法返回结果的状态
then方法返回:
1.如果回调函数结果是一个非Promise对象,则返回结果是一个成功的Promise
2.如果回调函数结果是一个Promise对象,则返回结果由该Promise对象决定
代码:
Promise.prototype.then = function(onResolved, onRejected) { const self = this //注意:函数内的this指向Window!!! return new Promise((resolve, reject) => { if (this.PromiseState === 'fulfilled') { try { // 来对应回调函数通过throw抛出异常 // console.log(this) //获取回调函数执行的结果 let result = onResolved(self.PromiseResult); //如果回调函数执行结果是Promise对象 if (result instanceof Promise) { result.then(val => { resolve(val); //是val 不是result }, rea => { reject(rea); //是rea 不是result }) } else { resolve(result); //此处应该返回是回调函数执行结果,而不是resolve函数执行结果 // result(this.PromiseResult) 不对 } } catch (e) { reject(e); } } if (this.PromiseState === 'rejected') { try { let result = onRejected(self.PromiseResult); if (result instanceof Promise) { result.then(val => { resolve(val); }, rea => { reject(rea); }) } else { resolve(result); } } catch (e) { reject(e); } } if (this.PromiseState === 'pending') { this.callback.push({ onResolved, onRejected }); } }); }
测试:
<script> let p = new Promise((resolve, reject) => { resolve('ok'); // reject('err'); // throw 'fail'; }) let res = p.then(value => { console.log(value); // return 123 /* return new Promise((resolve,reject) =>{ resolve('okk'); }) */ }, reason => { console.warn(reason); }) console.log(res); </script>
八、异步修改then方法返回结果的状态
代码:
Promise.prototype.then = function(onResolved, onRejected) { const self = this //注意:函数内的this指向Window!!! if (this.PromiseState === 'pending') { this.callback.push({ onResolved: function(){ try { let result = onResolved(self.PromiseResult); if (result instanceof Promise) { result.then(val => { resolve(val); }, rea => { reject(rea); }) } else { resolve(result); } } catch (e) { reject(e); } }, onRejected: function(){ try { let result = onRejected(self.PromiseResult); if (result instanceof Promise) { result.then(val => { resolve(val); }, rea => { reject(rea); }) } else { resolve(result); } } catch (e) { reject(e); } }); } }); }
测试:
<script> let p = new Promise((resolve, reject) => { setTimeout(()=>{ resolve('ok'); // reject('err'); // throw 'fail'; },1000) }) let res = p.then(value => { console.log(value); // return 123 /* return new Promise((resolve,reject) =>{ resolve('okk'); }) */ }, reason => { console.warn(reason); }) console.log(res); </script>
九、部分代码的优化
因为 then 方法返回结果处有大量重复代码,所有封装函数,优化代码
Promise.prototype.then = function(onResolved, onRejected) { const self = this; return new Promise((resolve, reject) => { function callback(type) { try { let result = type(self.PromiseResult); if (result instanceof Promise) { result.then(val => { resolve(val); }, rea => { reject(rea); }) } else { resolve(result); } } catch (e) { reject(e); } }
以上代码+注释整合:
function Promise(executor) { //executor:执行器函数,即同步执行函数 //一旦出现thorw语句,则使用 try...catch...来捕获 //给Promise构造函数身上添加两个固定的属性 this.PromiseState = 'pending'; this.PromiseResult = null; // this.callback = {} //用来保存当Promise里面执行的是异步函数时的then方法中的两个回调 this.callback = [] //当形式为数组是,则用来绑定多个回调 const self = this; //将self指向Promise function resolve(data) { // console.log(this) 函数体内的this指向window if (self.PromiseState !== 'pending') return; //此if语句使PromiseState只能修改一次 self.PromiseState = 'fulfilled'; self.PromiseResult = data; // if (self.callback.onResolved) self.callback.onResolved(data) //如果是异步执行,则callback中则会含有onResolved / onRejected // 当执行多个回调时使用数组形式来遍历调用 self.callback.forEach(item => { item.onResolved(data); }) } function reject(data) { if (self.PromiseState !== 'pending') return; //此if语句使PromiseState只能修改一次 self.PromiseState = 'rejected'; self.PromiseResult = data; // if (self.callback.onRejected) self.callback.onRejected(data) //如果是异步执行,则callback中则会含有onResolved / onRejected // 当执行多个回调时使用数组形式来遍历调用 self.callback.forEach(item => { item.onRejected(data); }) } try { executor(resolve, reject); } catch (e) { reject(e); } } Promise.prototype.then = function(onResolved, onRejected) { /* .then方法返回: 1.如果回调函数结果是一个非Promise对象,则返回一个成功的Promise 2.如果回调函数结果是一个Promise对象,则返回结果由该Promise对象决定 */ const self = this return new Promise((resolve, reject) => { function callback(type) { try { //获取回调函数执行的结果 // console.log(this),注意:函数内的this指向Window!!! let result = type(self.PromiseResult); //如果回调函数执行结果是Promise对象 if (result instanceof Promise) { result.then(val => { resolve(val); //是val 不是result }, rea => { reject(rea); //是rea 不是result }) } else { resolve(result); //此处应该返回是回调函数执行结果,而不是resolve函数执行结果 // result(this.PromiseResult) 不对 } } catch (e) { reject(e); } } if (this.PromiseState === 'fulfilled') callback(onResolved); //Promise成功时所执行的回调 if (this.PromiseState === 'rejected') callback(onRejected); //Promise失败时所执行的回调 //下面为当Promise里面是异步函数时所对应情况 if (this.PromiseState === 'pending') { // this.callback = { // onResolved, // onRejected // //对象的简写形式,相当于{onResolved:onResolved,onRejected,onRejected} // } // this.callback.push({ // onResolved, // onRejected // }) //异步修改then的返回结果 this.callback.push({ onResolved: function() { callback(onResolved); }, onRejected: function() { callback(onRejected); } }) } }) }