赞
踩
- 抽象表达:
- Promise是一门新的技术(ES6规范)
- Promise是JS中进行异步编程的新解决方案
备注:旧方案是单纯的使用回调函数
- 具体表达:
- 从语法上来说:Promise是一个构造函数
- 从功能上来说:Promise对象用来封装一个异步操作并可以获取其成功/失败的结果值
- pending变为resolved
- pending变为rejected
说明:只有这两种,且
一个promise对象只能改变一次状态
。无论变为成功还是失败,都会有一个结果数据。
- 成功的结果数据一般称为value,失败的结果数据一般称为reason
- 旧的:必须再启动异步任务前指定
- promise:启动异步任务 => 返回promise对象 => 给promise对象绑定回调函数(甚至可以再异步任务结束后指定/多个)
- 回调地狱:回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调执行的条件
- 回调地狱的缺点
- 不便于阅读
- 不便于一场处理
如下-.-,查看API
Promise构造函数:Promise (executor){}
- executor函数:执行器 {resolve, reject} => {}
- resolve函数:内部定义成功时我们调用的函数 value => {}
- reject函数:内部定义失败时我们调用的函数 reason => {}
说明:executor会在Promise内部立即同步调用,异步操作在执行器中执行
<script>
let pms = new Promise((resolve,reject) => {
// 成功 promise的value为'aaa' 同步调用
resolve('aaa')
})
console.log(pms)
</script>
Promise.prototype.then方法:(onResolved,onRejected) => {}
- onResolved函数:成功的回调函数 (value) => {}
- onRejected函数:失败的回调函数 (reason) => {}
说明:指定用于得到成功value的成功回调和用于得到失败reason的失败回调。返回一个新的Promise对象
<script> let pms1 = new Promise((resolve,reject) => { // 成功 promise的value为'aaa' resolve('aaa') }) let pms2 = new Promise((resolve,reject) => { // 失败 promise的value为'bbb' reject('bbb') }) let pms1Then = pms1.then(resolve => { // pms1成功了,会走这个 console.log("pms1 resolve",resolve) return resolve // return的值,作为pms2Then(promise对象)的result值。如果没有return,则默认undefined },reject => { console.log("pms1 reject",reject) }) let pms2Then = pms2.then(resolve => { console.log("pms2 resolve",resolve) },reject => { // pms2失败了,会走这个 console.log("pms2 reject",reject) return reject // return的值,作为pms2Then(promise对象)的result值 }) console.log("pms1Then",pms1Then) console.log("pms2Then",pms2Then) </script>
Promise.prototype.catch方法:(onRejected) => {}
- onRejected函数:失败的回调函数 (reason) => {}
说明:它是
Promise.prototype.then(undefined, onRejected)
的快捷方式
<script> let pms1 = new Promise((resolve,reject) => { // 成功 promise的value为'aaa' resolve('aaa') }) let pms2 = new Promise((resolve,reject) => { // 失败 promise的value为'bbb' reject('bbb') }) let pms1Then = pms1.then(resolve => { // pms1成功了,会走这个 console.log("pms1 resolve",resolve) return resolve },reject => { console.log("pms1 reject",reject) }) let pms2Catch = pms2.catch((reject => { console.log("pm2 catch",reject) return reject })) console.log("pms1Then",pms1Then) console.log("pms2Catch",pms2Catch) </script>
Promise.prototype.finally:() => {}
- 不管状态如何,都会执行的函数
<script> let pms1 = new Promise((resolve,reject) => { // 成功 promise的value为'aaa' resolve('aaa') }) pms1.then(resolve => { console.log(resolve) // console.log("pms1回调方法执行完毕") },reject => { console.log(reject) // console.log("pms1回调方法执行完毕") }) pms1.finally(()=>{ console.log("pms1回调方法执行完毕") }) </script>
Promise.resolve方法:(value) => {}
- value:成功的数据或promise对象
- 如果参数是一个基本数据类型,则返回成功的promise对象,promise对象的值为传入的参数
- 如果参数是一个promise对象,则返回的promise对象的结果,是根据参数(promise对象)的结果来判断,如果参数promise对象成,则返回的promise对象的结果也是成功,反之失败。值也为参数promise对象返回的值
说明:返回一个成功/失败的promise对象
<script>
let pms = Promise.resolve('aaa')
console.log(pms)
</script>
<script>
let p1 = new Promise((resolve,reject) => {
resolve('我成功啦')
})
let p2 = new Promise((resolve,reject) => {
reject('我失败了')
})
let pms1 = Promise.resolve(p1)
let pms2 = Promise.resolve(p2)
console.log(pms1)
console.log(pms2)
</script>
Promise.reject方法:(reason) => {}
- reason:失败的原因
- 不管参数为基本数据类型还是promise对象,返回的promise对象始终为失败的
说明:返回一个失败的promise对象
<script>
let p2 = new Promise((resolve,reject) => {
reject('我失败了')
})
let pms1 = Promise.reject('我成功啦')
let pms2 = Promise.reject(p2)
console.log(pms1)
console.log(pms2)
</script>
Promise.all方法:(promises) => {}
- promises:包含n个promise的数组
- 返回的新的promise值为所有promise成功的值组成的数组,数组顺序与参数数组中promise的顺序一致
说明:返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败了,就直接失败,返回的结果为失败的promise的结果
<script>
let p1 = Promise.resolve('aaa')
let p2 = Promise.resolve('bbb')
let p3 = Promise.resolve('ccc')
let pms1 = Promise.all([p1,p2,p3])
console.log(pms1)
</script>
<script>
let p1 = Promise.reject('aaa') // 失败
let p2 = Promise.resolve('bbb')
let p3 = Promise.resolve('ccc')
let pms1 = Promise.all([p1,p2,p3])
console.log(pms1)
</script>
Promise.race方法:(promises) => {}
- promises:包含n个promise的数组
说明:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
<script>
let p1 = new Promise((resolve,reject) => {
setTimeout(()=>{
resolve('aaa')
})
})
let p2 = new Promise((resolve,reject) => {
resolve('bbb')
})
let pms1 = Promise.race([p1,p2]);
console.log(pms1)
</script>
- resolve(value):如果当前时pending就会变为resolved
- reject(reason):如果当前时pending就会变为rejected
- 抛出异常:如果当前是pending就会变为rejected
<script> let p1 = new Promise((resolve,reject) => { resolve('aaa') }) let p2 = new Promise((resolve,reject) => { reject('bbb') }) let p3 = new Promise((resolve,reject) => { throw 'ccc'; }) console.log("p1",p1) // 成功 console.log("p2",p2) // 失败 console.log("p3",p3) // 失败 </script>
当promise改变为对应状态时都会调用
<script>
let p1 = new Promise((resolve,reject) => {
resolve('aaa')
})
p1.then((resolve) => {
console.log('aaa1:',resolve)
})
p1.then((resolve) => {
console.log('aaa2:',resolve)
})
</script>
- 都有可能,正常情况下实现指定回调再改变状态,但也可以先改变状态再指定回调
- 如何先改状态再指定回调?
- 再执行器中直接调用resolve()/reject()
- 延迟更长时间才调用then()
- 什么时候才能得到数据?
- 如果先指定的回调,那当状态发生改变时,回调函数就会调用,得到数据
- 如果先改变的状态,那当指定回调时,回调函数就会调用,得到数据
<script> let p1 = new Promise((resolve,reject) => { // 1.先改变状态 resolve('aaa') }) p1.then(resolve => { // 2.调用回调函数 }) // ----------------------------------------------------- let p2 = new Promise((resolve,reject) => { // 2.然后改变状态 setTimeout(() => { resolve('aaa') },1000) }) // 1.先指定回调 p2.then(resolve => { // 3.状态改变后回调函数调用。 }) </script>
- 简单表达:由then()指定的回调函数执行的结果决定
- 详细表达:
- 如果抛出异常,新promise变为rejected,reason为抛出的异常
- 如果返回的是非promise的任意值,新promise变为resolved,value为返回的值
- 如果返回的是另一个新promise,此promise的结果就会成为新promise的结果
<script> let p1 = new Promise((resolve,reject) => { // 1.先改变状态 resolve('aaa') }) // 非promise的任意值 let pThen1 = p1.then(value => { return 'pThen1' }) console.log("pThen1:",pThen1) // 成功 // 抛出异常 let pThen2 = p1.then(value => { throw 'pThen2' }) console.log("pThen2:",pThen2) // 失败 // 返回失败的promise let pThen3 = p1.then(value => { return new Promise((resolve,reject) => { reject('pThen3') }) }) console.log("pThen3:",pThen3) // 失败 </script>
- promise的then()返回一个新的promise,可以看成then()的链式调用
- 通过then的链式调用串连多个同步/异步任务
<script> let p1 = new Promise((resolve,reject) => { // 1.等待1秒 setTimeout(()=>{ console.log('aaa') resolve(true) },1000) }) p1.then(value => { // 2.执行回调 return new Promise((resolve,reject) => { // 3.等待1秒 setTimeout(()=>{ console.log('bbb') resolve('ccc') },1000) }) }).then(value => { // 4.成功的promise。执行回调 console.log(value) // ccc }) </script>
- 当使用promise的then链式调用时,可以在最后指定失败的回调
- 前面任何操作出了异常,都会传到最后失败的回调中处理
<script> let p1 = new Promise((resolve,reject) => { setTimeout(()=>{ console.log('aaa') // 链子地方任意一处失败,只需要在链子的最后面写一个catch即可获取到 reject(false) },1000) }) p1.then(value => { return new Promise((resolve,reject) => { console.log('bbb') resolve('ccc') }) }).then(value => { console.log(value) // ccc }).catch(reason => { // 上面的链子中,不管哪个地方失败,都会走catch方法 console.error(reason) }) </script>
- 当使用promise的then链式调用时,在中间中断,不再调用后面的回调函数
- 办法:再回调函数中返回一个pendding状态的promise对象
<script> let p1 = new Promise((resolve,reject) => { setTimeout(()=>{ console.log('aaa') resolve(true) },1000) }) p1.then(value => { // 想在这里执行完后,不走下面回调 console.log('bbb') return new Promise((resolve,reject) => { // 这个promise为pending状态 }) }).then(value => { console.log('ccc') }).catch(reason => { console.error(reason) }) </script>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- 引入手写Promise --> <script src="./test1.js"></script> </head> <body> <script> let p = new Promise((resolve,reject) => { resolve("OK") }) p.then(value => { console.log(value) },reason => { console.log(reason) }) </script> </body> </html>
function Promise(executor) {
function resolve(data){
}
function reject(data){
}
executor(resolve,reject);
}
Promise.prototype.then = function(onResolve,onReject){
}
function Promise(executor) { // 初始状态为 pendding this.PromiseState = 'pendding'; this.PromiseResult = null; let that = this; function resolve(data){ // 首先改变状态 PromiseState属性 that.PromiseState = 'fulfilled' // 然后给结果赋值 PromiseResult属性 that.PromiseResult = data; } function reject(data){ // 首先改变状态 PromiseState属性 that.PromiseState = 'rejected' // 然后给结果赋值 PromiseResult属性 that.PromiseResult = data; } executor(resolve,reject); } Promise.prototype.then = function(onResolve,onReject){ }
抛出异常后,Promise会变为失败状态,失败后的值,就是throw的内容。
只需要把 executor try catch住即可
<script>
let p = new Promise((resolve,reject) => {
// reject("OK")
throw "error"
})
p.then(value => {
console.log(value)
},reason => {
console.log(reason)
})
console.log(p)
</script>
function Promise(executor) { this.PromiseState = 'pendding'; this.PromiseResult = null; let that = this; function resolve(data){ // 首先改变状态 PromiseState属性 that.PromiseState = 'fulfilled'; // 然后给结果赋值 PromiseResult属性 that.PromiseResult = data; } function reject(data){ // 首先改变状态 PromiseState属性 that.PromiseState = 'rejected'; // 然后给结果赋值 PromiseResult属性 that.PromiseResult = data; } // 抛出异常 try { executor(resolve,reject); }catch (e) { // that.PromiseState = 'rejected'; // that.PromiseResult = e; reject(e) } } Promise.prototype.then = function(onResolve,onReject){ }
想要状态修改一次,我们只需要在修改状态前进行判断即可
<script>
let p = new Promise((resolve,reject) => {
resolve("ok") // 只走这一次
reject("error")
})
p.then(value => {
console.log(value)
},reason => {
console.log(reason)
})
console.log(p)
</script>
function Promise(executor) { this.PromiseState = 'pendding'; this.PromiseResult = null; let that = this; function resolve(data){ if (that.PromiseState === 'pendding'){ // 判断状态是否改变 // 首先改变状态 PromiseState属性 that.PromiseState = 'fulfilled'; // 然后给结果赋值 PromiseResult属性 that.PromiseResult = data; } } function reject(data){ if (that.PromiseState === 'pendding') { // 首先改变状态 PromiseState属性 that.PromiseState = 'rejected'; // 然后给结果赋值 PromiseResult属性 that.PromiseResult = data; } } // 抛出异常 try { executor(resolve,reject); }catch (e) { reject(e) } } Promise.prototype.then = function(onResolve,onReject){ }
执行回调,判断promise状态,执行相应的回调函数
function Promise(executor) { this.PromiseState = 'pendding'; this.PromiseResult = null; let that = this; function resolve(data){ if (that.PromiseState === 'pendding'){ // 判断状态是否改变 // 首先改变状态 PromiseState属性 that.PromiseState = 'fulfilled'; // 然后给结果赋值 PromiseResult属性 that.PromiseResult = data; } } function reject(data){ if (that.PromiseState === 'pendding') { // 首先改变状态 PromiseState属性 that.PromiseState = 'rejected'; // 然后给结果赋值 PromiseResult属性 that.PromiseResult = data; } } // 抛出异常 try { executor(resolve,reject); }catch (e) { reject(e) } } Promise.prototype.then = function(onResolve,onReject){ // 由于是p(promise)调用then方法,所以我们可以使用this if(this.PromiseState === 'fulfilled'){ onResolve(this.PromiseResult) }else if(this.PromiseState === 'rejected'){ onReject(this.PromiseResult) } }
1.then回调函数异步
此时我们把引入的js文件注释掉,可以发现,then方法是异步任务,先打印的P,然后再执行then方法里的函数。我们这个是先执行then方法里的函数,然后才打印的p,在then方法里调用回调函数外面包一层setTimeout即可
2.executor函数异步
当executor函数为异步函数时,then回调函数要等executor执行完毕后,再执行。所以我们要在executor执行完毕后再调用then方法
<script>
let p = new Promise((resolve,reject) => {
setTimeout(() => {
resolve("ok")
},1000)
})
p.then(value => {
console.log(value)
},reason => {
console.log(reason)
})
console.log("p",p)
</script>
function Promise(executor) { this.PromiseState = 'pendding'; this.PromiseResult = null; this.callBack = {}; let that = this; function resolve(data){ if (that.PromiseState === 'pendding'){ // 判断状态是否改变 // 首先改变状态 PromiseState属性 that.PromiseState = 'fulfilled'; // 然后给结果赋值 PromiseResult属性 that.PromiseResult = data; // 执行完毕后,调用then方法 if(that.callBack.res){ that.callBack.res(data) } } } function reject(data){ if (that.PromiseState === 'pendding') { // 首先改变状态 PromiseState属性 that.PromiseState = 'rejected'; // 然后给结果赋值 PromiseResult属性 that.PromiseResult = data; // 执行完毕后,调用then方法 if(that.callBack.rej){ that.callBack.rej(data) } } } // 抛出异常 try { executor(resolve,reject); }catch (e) { reject(e) } } Promise.prototype.then = function(onResolve,onReject){ setTimeout(() => { // 由于是p(promise)调用then方法,所以我们可以使用this if(this.PromiseState === 'fulfilled'){ onResolve(this.PromiseResult); }else if(this.PromiseState === 'rejected'){ onReject(this.PromiseResult); }else if(this.PromiseState === 'pendding'){ // 需要先把方法保存起来,才能在上面调用 this.callBack.res = onResolve; this.callBack.rej = onReject; } }) }
当我们按照上面的代码写的时候,这时候当我们执行两个then方法,这时候只会走最后一个方法,因为最后一个方法在
then
方法里,把上面的方法替换掉了,所以只会走最后一个,这时候我们要把callBack变为数组,遍历以此执行
<script> let p = new Promise((resolve,reject) => { setTimeout(() => { resolve("ok") },1000) }) p.then(value => { console.log('111') },reason => { console.log(reason) }) p.then(value => { console.log('222') },reason => { console.log(reason) }) console.log("p",p) </script>
function Promise(executor) { this.PromiseState = 'pendding'; this.PromiseResult = null; this.callBack = []; let that = this; function resolve(data){ if (that.PromiseState === 'pendding'){ // 判断状态是否改变 // 首先改变状态 PromiseState属性 that.PromiseState = 'fulfilled'; // 然后给结果赋值 PromiseResult属性 that.PromiseResult = data; // 执行完毕后,调用then方法 that.callBack.forEach(item => { item.res(data); }) } } function reject(data){ if (that.PromiseState === 'pendding') { // 首先改变状态 PromiseState属性 that.PromiseState = 'rejected'; // 然后给结果赋值 PromiseResult属性 that.PromiseResult = data; // 执行完毕后,调用then方法 that.callBack.forEach(item => { item.rej(data); }) } } // 抛出异常 try { executor(resolve,reject); }catch (e) { reject(e) } } Promise.prototype.then = function(onResolve,onReject){ setTimeout(() => { // 由于是p(promise)调用then方法,所以我们可以使用this if(this.PromiseState === 'fulfilled'){ onResolve(this.PromiseResult); }else if(this.PromiseState === 'rejected'){ onReject(this.PromiseResult); }else if(this.PromiseState === 'pendding'){ // 需要先把方法保存起来,才能在上面调用 this.callBack.push({ res:onResolve, rej:onReject }) } }) }
then方法要返回一个promise对象,
如果返回值为promise外其他类型,则为成功的promise,值为返回的值
如果返回值为promise类型,则根据这个promise的返回结果来改变返回值的返回结果
<script> let p = new Promise((resolve,reject) => { // setTimeout(() => { resolve("ok") // },1000) }) let then1 = p.then(value => { console.log('111') // 返回的是undefined },reason => { console.log(reason) }) let then2 = p.then(value => { return new Promise((resolve,reject) => { resolve('OOKK') }) },reason => { console.log(reason) }) console.log("then1",then1) console.log("then2",then2) </script>
Promise.prototype.then = function(onResolve,onReject){ return new Promise((resolve,reject) => { setTimeout(() => { // 由于是p(promise)调用then方法,所以我们可以使用this if(this.PromiseState === 'fulfilled'){ const resout = onResolve(this.PromiseResult); if (resout instanceof Promise){ resout.then(value => { resolve(value); },reason => { reject(reason); }) }else { resolve(resout); } }else if(this.PromiseState === 'rejected'){ const resout = onReject(this.PromiseResult); if (resout instanceof Promise){ resout.then(value => { resolve(value); },reason => { reject(reason); }) }else { resolve(resout); } }else if(this.PromiseState === 'pendding'){ // 需要先把方法保存起来,才能在上面调用 this.callBack.push({ res:onResolve, rej:onReject }) } }) }) }
由于executor执行完毕后只会执行回调,并不会执行回调中promise中的resolve和reject方法,导致then方法返回的promise始终为
pendding
状态并且我们要判断then里面throw抛出异常后promise的状态
<script> let p = new Promise((resolve,reject) => { setTimeout(() => { resolve("ok") },1000) }) let then1 = p.then(value => { console.log(value) // 返回的是undefined },reason => { console.log(reason) }) let then2 = p.then(value => { return 'OOKK' },reason => { console.log(reason) }) let then3 = p.then(value => { throw 'error' },reason => { console.log(reason) }) console.log(then1) console.log(then2) console.log(then3) </script>
Promise.prototype.then = function(onResolve,onReject){ return new Promise((resolve,reject) => { setTimeout(() => { // 由于是p(promise)调用then方法,所以我们可以使用this if(this.PromiseState === 'fulfilled'){ try { const result = onResolve(this.PromiseResult); if (result instanceof Promise){ result.then(value => { resolve(value); },reason => { reject(reason); }) }else { resolve(result); } }catch (e) { reject(e); } }else if(this.PromiseState === 'rejected'){ try { const result = onReject(this.PromiseResult); if (result instanceof Promise){ result.then(value => { resolve(value); },reason => { reject(reason); }) }else { resolve(result); } }catch (e) { reject(e) } }else if(this.PromiseState === 'pendding'){ // 需要先把方法保存起来,才能在上面调用 this.callBack.push({ res: () => { try { // 获取then回调的返回值 let result = onResolve(this.PromiseResult) if (result instanceof Promise){ result.then(value => { resolve(value); },reason => { reject(reason); }) }else { resolve(result); } }catch (e) { reject(e) } }, rej: () => { try { let result = onReject(this.PromiseResult) if (result instanceof Promise){ result.then(value => { resolve(value); },reason => { reject(reason); }) }else { resolve(result); } }catch (e) { reject(e); } }, }) } }) }) }
then方法里很多代码是重复代码,我们需要单独提取出来
Promise.prototype.then = function(onResolve,onReject){ return new Promise((resolve,reject) => { setTimeout(() => { // 封装函数 const handleThen = (type) => { try { const result = type(this.PromiseResult); if (result instanceof Promise){ result.then(value => { resolve(value); },reason => { reject(reason); }) }else { resolve(result); } }catch (e) { reject(e); } } // 由于是p(promise)调用then方法,所以我们可以使用this if(this.PromiseState === 'fulfilled'){ handleThen(onResolve); }else if(this.PromiseState === 'rejected'){ handleThen(onReject); }else if(this.PromiseState === 'pendding'){ // 需要先把方法保存起来,才能在上面调用 this.callBack.push({ res: () => { handleThen(onResolve); }, rej: () => { handleThen(onReject); }, }) } }) }) }
<script>
let p = new Promise((resolve,reject) => {
setTimeout(() => {
reject("error")
},1000)
})
p.catch(e => {
console.log(e)
})
console.log(p)
</script>
Promise.prototype.catch = function (onReject){
return this.then(undefined,onReject);
}
- 如果promise途中失败了,在then里面只写成功的回调方法,不写失败的,那么控制台就会报错,找不到onReject方法,我们要判断如果没有方法,就默认加一个
- 当我第一个then什么回调都没有写的时候,值会传递到第二个then中,并且顺利执行
<script>
let p = new Promise((resolve,reject) => {
setTimeout(() => {
resolve("error")
},1000)
})
p.then().then(value => {
console.log(value + '1')
}).then(value => {
console.log(value + '2')
}).catch(reason => {
console.log(reason + '3')
})
</script>
Promise.prototype.then = function(onResolve,onReject){ return new Promise((resolve,reject) => { // 处理失败回调没有的情况 if (typeof onReject !== "function"){ // 往上抛,直到抛到catch onReject = reason => { throw reason }; } // 处理成功回调没有的情况 if(typeof onResolve !== "function"){ onResolve = value => { return value } } setTimeout(() => { // 封装函数 const handleThen = (type) => { try { const result = type(this.PromiseResult); if (result instanceof Promise){ result.then(value => { resolve(value); },reason => { reject(reason); }) }else { resolve(result); } }catch (e) { reject(e); } } // 由于是p(promise)调用then方法,所以我们可以使用this if(this.PromiseState === 'fulfilled'){ handleThen(onResolve); }else if(this.PromiseState === 'rejected'){ handleThen(onReject); }else if(this.PromiseState === 'pendding'){ // 需要先把方法保存起来,才能在上面调用 this.callBack.push({ res: () => { handleThen(onResolve); }, rej: () => { handleThen(onReject); }, }) } }) }) }
<script>
let p1 = Promise.resolve('111')
let p2 = Promise.resolve(new Promise((resolve,reject) => {resolve('OK')}))
let p3 = Promise.resolve(new Promise((resolve,reject) => {reject('ERROR')}))
let p4 = Promise.resolve(new Promise((resolve,reject) => {throw 'error'}))
console.log("p1",p1)
console.log("p2",p2)
console.log("p3",p3)
console.log("p4",p4)
</script>
Promise.resolve = function (data){
return new Promise((onResolve,onReject) => {
if (data instanceof Promise){
data.then(resolve => {
onResolve(resolve)
},reject => {
onReject(reject)
})
}else {
onResolve(data)
}
})
}
<script>
let p1 = Promise.reject('111')
let p2 = Promise.reject(new Promise((resolve,reject) => {resolve('OK')}))
let p3 = Promise.reject(new Promise((resolve,reject) => {reject('ERROR')}))
let p4 = Promise.reject(new Promise((resolve,reject) => {throw 'error'}))
console.log("p1",p1)
console.log("p2",p2)
console.log("p3",p3)
console.log("p4",p4)
</script>
Promise.reject = function (data){
return new Promise((resolve,reject) => {
reject(data)
})
}
<script>
let p1 = Promise.resolve('111')
let p2 = new Promise((resolve,reject) => {
resolve('OK2')
})
let p3 = new Promise((resolve,reject) => {
// reject('Error3')
resolve('OK3')
})
let all = Promise.all([p1,p2,p3,'aaa']);
console.log(all)
</script>
Promise.all = function (datas){ return new Promise((onResolve,onReject) => { let resouts = [] let count = 0; for (let i = 0; i < datas.length; i++) { const data = datas[i]; debugger if(data instanceof Promise){ data.then(resolve => { resouts[i] = resolve; count++; if(count === datas.length){ onResolve(resouts) } },reject => { onReject(reject) }) }else { resouts[i] = data count++; if(count === datas.length){ onResolve(resouts) } } } }) }
<script>
let p1 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('OK1')
})
})
let p2 = new Promise((resolve,reject) => {
resolve('OK2')
})
let all = Promise.race([p1,p2,'aaa']);
console.log(all)
</script>
Promise.race = function (datas){ return new Promise((onResolve,onReject) => { for (let i = 0; i < datas.length; i++) { let data = datas[i]; if(data instanceof Promise){ data.then(value => { onResolve(value) },reason => { onReject(reason) }) }else { // 弥补then方法的异步时间 setTimeout(() => { onResolve(data); }) } } }) }
注意:静态方法前面要添加
static
关键字!!!
class Promise { constructor(executor) { this.PromiseState = 'pendding'; this.PromiseResult = null; this.callBack = []; let that = this; function resolve(data){ if (that.PromiseState === 'pendding'){ // 判断状态是否改变 // 首先改变状态 PromiseState属性 that.PromiseState = 'fulfilled'; // 然后给结果赋值 PromiseResult属性 that.PromiseResult = data; // 执行完毕后,调用then方法 that.callBack.forEach(item => { item.res(data); }) } } function reject(data){ if (that.PromiseState === 'pendding') { // 首先改变状态 PromiseState属性 that.PromiseState = 'rejected'; // 然后给结果赋值 PromiseResult属性 that.PromiseResult = data; // 执行完毕后,调用then方法 that.callBack.forEach(item => { item.rej(data); }) } } // 抛出异常 try { executor(resolve,reject); }catch (e) { reject(e) } } then(onResolve,onReject) { return new Promise((resolve, reject) => { // 处理失败回调没有的情况 if (typeof onReject !== "function") { // 往上抛,直到抛到catch onReject = reason => { throw reason }; } // 处理成功回调没有的情况 if (typeof onResolve !== "function") { onResolve = value => { return value } } setTimeout(() => { // 封装函数 const handleThen = (type) => { try { const result = type(this.PromiseResult); if (result instanceof Promise) { result.then(value => { resolve(value); }, reason => { reject(reason); }) } else { resolve(result); } } catch (e) { reject(e); } } // 由于是p(promise)调用then方法,所以我们可以使用this if (this.PromiseState === 'fulfilled') { handleThen(onResolve); } else if (this.PromiseState === 'rejected') { handleThen(onReject); } else if (this.PromiseState === 'pendding') { // 需要先把方法保存起来,才能在上面调用 this.callBack.push({ res: () => { handleThen(onResolve); }, rej: () => { handleThen(onReject); }, }) } }) }) } catch(onReject){ return this.then(undefined,onReject); } static resolve(data){ return new Promise((onResolve,onReject) => { if (data instanceof Promise){ data.then(resolve => { onResolve(resolve) },reject => { onReject(reject) }) }else { onResolve(data) } }) } static reject(data){ return new Promise((resolve,reject) => { reject(data) }) } static all(datas){ return new Promise((onResolve,onReject) => { let resouts = [] let count = 0; for (let i = 0; i < datas.length; i++) { const data = datas[i]; debugger if(data instanceof Promise){ data.then(resolve => { resouts[i] = resolve; count++; if(count === datas.length){ onResolve(resouts) } },reject => { onReject(reject) }) }else { resouts[i] = data count++; if(count === datas.length){ onResolve(resouts) } } } }) } static race(datas){ return new Promise((onResolve,onReject) => { for (let i = 0; i < datas.length; i++) { let data = datas[i]; if(data instanceof Promise){ data.then(value => { onResolve(value) },reason => { onReject(reason) }) }else { // 弥补then方法的异步时间 setTimeout(() => { onResolve(data); }) } } }) } }
async
函数的返回值为promise对象
promise对象的结果由async函数执行的返回值决定
<script> async function test1(){ return 'aaa' } async function test2(){ return new Promise((resolve,reject) => { resolve("我成功啦") }) } console.log("test1",test1()) console.log("test2",test2()) </script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
await
await右侧的表达式一般为promise对象,但也可以是其它的值
如果表达式是promise对象,await返回的结果时promise成功的值
如果表达式是其它值,直接将此值作为await的返回值
<script> async function test1(){ let a = await 'aaa'; console.log("a",a); let b = await Promise.resolve('bbb') console.log("b",b) } test1() </script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
注意
await必须卸载async函数中,但async函数中可以没有await
如果await的promise失败了,就会抛出异常,需要通过try…catch捕获处理
<script> /*function test1(){ 报错 await 'aaa'; }*/ async function test1(){ let a = ''; try { // 失败 p = new Promise((resolve,reject) => { reject('我失败了') }) // 抛出异常 a = await p; }catch (e){ a = '我真的失败了' } console.log(a) } test1() </script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
OK,Promise课程到此结束,欢迎下期再见~Bye
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。