Promise.js
/*
*自定义模块 :函数
* */
;(function (params){
//传入一个执行器:同步执行
/*
new Promise((resolve,reject)=>{
resolve(1)//成功
reject('失败')
})
* */
//调用执行器之前,要准备用于改变promise状态的函数
function Promise(executor){
//这个that 在当前函数作用域里面保存
const that = this //先保存
that.status = 'pending' //给promise对象指定status属性,初始值为pending
that.data = undefined //给promise对象指定一个用于存储数据的属性 ===外面传递过来的
that.callbacks = [] //每个元素的构造 {onResolved=>{},onRejected=>{}}
//立即执行执行器 同步
function resolve(value){
//状态只能改变一次
if(that.status !== 'pending'){
return
}
//将状态改为resolved
that.status = 'resolved'
//保存value数据
that.data = value
//如果有待执行的callback函数,立即 异步执行回调函数
if(that.callbacks.length>0){
setTimeout(()=>{
that.callbacks.forEach(callbacksObj=>{
callbacksObj.onResolved(value)
})
})
}
}
function reject(reason){
//状态只能改变一次
if(that.status !== 'pending'){
return
}
//将状态改为resolved
that.status = 'rejected'
//保存value数据
that.data = reason
//如果有待执行的callback函数,立即异步执行回调函数
if(that.callbacks.length>0){
setTimeout(()=>{
that.callbacks.forEach(callbacksObj=>{
callbacksObj.onRejected(reason)
})
})
}
}
try{
//执行器抛出异常 直接reject
//同步执行。
//传递过来的一个函数 (resolve,reject)=>{}
executor(resolve,reject)
}catch(error){
reject(error)
}
}
/*
new Promise((resolve,reject)=>{
}).then(
value=>{},
reasonal=>{}
)
*
* */
//实例对象的then
//指定成功或者失败的回调方法
//返回一个新的promise的结果由onResolved 和onRejected执行的结果决定
Promise.prototype.then = function(onResolved,onRejected){
//向下传递value
//没有指定onResolved/ 则onResolved: value=>value//我们帮天写
onResolved = typeof onResolved === 'function'?onResolved:value=>value
//指定默认的失败的回调(实现错误/异常串透的关键点)
//没有指定onRejected/ 则onRejectedd: reason=>{throw reason}//我们帮他写
onRejected = typeof onRejected === 'function'?onRejected:reason=>{throw reason}
//可以不保存 this
//因为then这个函数就是通过 promise实例去调用的,每一个实例都有唯一的callbacks
const that = this //也要保存一下
//返回一个新的promise对象
return new Promise((resolve,reject)=>{
//可能调用resolve,可能调用reject
//调用哪个需要 前一个promise的执行结果,他的执行结果在
function handler(callback){
try{
const ret = callback(that.data)
if(ret instanceof Promise){
ret.then(resolve,reject);
}else{
//返回的是 非Promise对象
//需要改变 返回的promise的状态--为成功
resolve(ret)
}
}catch(e){
//第一种情况
reject(e)//修改状态
}
}
//pending状态,
//回调函数已经保存
//某一时刻,修改了状体,直接进行调用回调
//并且返回已经修改状态的promise
if(that.status === 'pending'){
that.callbacks.push({
onResolved:function(value){
handler(onResolved)
},
onRejected:function(resonal){
handler(onRejected)
}
})
//先修改状态,然后执行回调函数
}else if(that.status === 'resolved'){
//异步处理成功回调
setTimeout(()=>{
handler(onResolved)
})
}else{
//异步处理失败回调
setTimeout(()=>{
handler(onRejected)
})
}
})
}
//实例对象的catch
//指定失败的回调方法
//返回一个promise
Promise.prototype.catch = function(onRejected){
//在then里面 可能会处理 成功,向下执行
//因为.catch().then()
return this.then(undefined,onRejected)
}
//函数对象的reject
//Promise.reject(1)
//返回一个失败的promise
Promise.reject = function(resonal){
}
//函数对象的resolve
Promise.reject(2)
//返回一个成功的promise
Promise.resolve = function(value){
//返回一个成功的或者失败的promise
return new Promise((resolve,reject)=>{
//value 是promise对象
if(value instanceof Promise){
//根据value的结果为 返回promise的结果
//value 执行的结果 传递给resolve,传递给reject --简写
//value.then(resolve,reject)
value.then(value=>{
resolve(value)//修改状态
},reason=>{
reject(reason)//修改状态
})
}else{
resolve(value)//修改返回的状态为成功
}
//value 不是promise对象
})
}
Promise.reject = function(reason){
return new Promise((resolve,reject)=>{
reject(reason)
})
}
//返回一个promise,只有当所有promise都成功时才成功,
//否则就失败了
Promise.all = function(promises){
const values = new Array(promises.length)//保存所有成功value的数组
//成功的数量
let resolveCounte = 0
return new Promise((resolve,reject)=>{
//遍历每一个promise的结果
promises.forEach((p,index)=>{
//取到p的结果
//改进,进行包装,防止传过来一个 7这类*********************
Promise.resolve(p).then(
value=>{
//p成功了,将成功的值保存到数组中
values[index] = value
resolveCounte++
//如果全部成功,将return的promise 改成成功
if(resolveCounte === values.length){
resolve(values)
}
},
//只要有一个失败,整个就失败了
//不会掉两次---不是pending就不进行调用
//阻止了多次调用
reasonal=>{
reject(reasonal)
}
)
})
})
}
//返回一个promise 器结果由第一个promise完成的确定
Promise.race = function(promises){
return new Promise((resolve,reject)=>{
promises.forEach((p,index)=>{
//取到p的结果
Promise.resolve(p).then(//*********************改进
//不会掉两次---不是pending就不进行调用
value=>{//一旦成功就返回
resolve(value)
},
//只要有一个失败,整个就失败了
//不会掉两次---不是pending就不进行调用
//阻止了多次调用
reasonal=>{
reject(reasonal)
}
)
})
})
}
//返回一个promise对象,在指定的时间后才确定结果
Promise.resolveDelay=function(value,time){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
//value 是promise对象
if(value instanceof Promise){
//根据value的结果为 返回promise的结果
//value 执行的结果 传递给resolve,传递给reject --简写
//value.then(resolve,reject)
value.then(value=>{
resolve(value)//修改状态
},reason=>{
reject(reason)//修改状态
})
}else{
resolve(value)//修改返回的状态为成功
}
},time)
})
}
//返回一个promise对象,在指定的时间后才确定结果
Promise.rejectDelay=function(reason,time){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
reject(reason)
},time)
})
}
//暴露
window.Promise = Promise
})(window)
测试
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script type="text/javascript" src="lib/Promise.js" ></script>
<script type="text/javascript">
const p = Promise.rejectDelay(3,3000)
p.catch(
resonal =>{
console.log(resonal)
}
)
const p2 = Promise.resolveDelay(3,3000)
p2.then(
value =>{
console.log(value)
}
)
</script>
</html>
其中Promise.js中的then缩写部分来源
//重要的点。改变返回promise的状态
//实例对象的then
//指定成功或者失败的回调方法
//返回一个新的promise的结果由onResolved 和onRejected执行的结果决定
Promise.prototype.then = function(onResolved,onRejected){
//可以不保存 this
//向下传递value
//没有指定onResolved/ 则onResolved: value=>value//我们帮他写
//return 1
onResolved = typeof onResolved === 'function'?onResolved:value=>value
//指定默认的失败的回调(实现错误/异常串透的关键点)
//没有指定onRejected/ 则onRejectedd: reason=>{throw reason}//我们帮他写
onRejected = typeof onRejected === 'function'?onRejected:reason=>{throw reason}
//因为then这个函数就是通过 promise实例去调用的,每一个实例都有唯一的callbacks
//这次的
const that = this //也要保存一下
//返回一个新的promise对象
return new Promise((resolve,reject)=>{
//可能调用resolve,可能调用reject
//调用哪个需要 前一个promise的执行结果,他的执行结果在
if(that.status === 'pending'){
// 状态为pending,先保存回调函数
//一旦成功就会调用onResolved 这个方法
//执行完这个方法后,为什么要影响返回promise的状态呢?
//因为.then 返回的也是Promise对象
//也就是当前状态还没有被修改,先执行了then,然后才会去改变状态
//改变状态的时候 立即执行回调函数---在执行器里面异步执行回调
//保存了回调函数
that.callbacks.push({
//从pendding---》成功状态的时候,就会调用这个回调
onResolved:function(value){//或者that.data
//不需要包裹setTimeOut() 因为在执行器执行的时候
//已经包裹了一层setTimeout
//然后执行的结果====》修改返回的状态
//onResolved(that.data);//或者value
//拷贝一下代码
try{
//回调函数一执行。
/*
状态还没改,是通过构造器返回的两个函数修改状体的。
但是我们先 执行了.then(回调1,回调2),将这两个回调放在 数组中
将来某一天,状态修改了,就会执行onResolved方法
也就是执行了.then(onResolved,onRejected) 在构造器里面调用的
调了onResolved方法---》返回了新的promise对象
return new Promise((resolved,rejected)=>{
可能在这里面调用构造器的方法了 修改状态的方法
resolved(value)或者rejecte(reason) //状态改了,值也保存了
//但是此时的回到函数没有哦
})
返回了新的实例----》传一个函数过去
构造器返回两个函数过来===》
所以就通过ret.then(进行push函数)
* */
const ret = onResolved(that.data)
if(ret instanceof Promise){
//返回的promise
//that.then(resolve=>{} return new Promise})
//这个返回的promise的状态已经被修改了
//只需要指定,他往哪走
//**********************************
//ret promise实例会进行回调
//执行下面value---》 代表ret的状态为成功
//执行下面的resonal---》 代表ret的状态为失败
/*ret.then(
value=>{
resolve(value)//修改状态
},resonal=>{
reject(resonal)//修改状态
}*/
//*********************************************
//简写由来
/*
function fn(event){
}
div.onclick = function(event){
fn(event)
}
/修改
div.onclick = fn //就可以实现了传递参数的问题了
* */
//***************************************
//回调函数 传递 参数 过去,然后我再调用
//所以可以简写
//给返回的promise 进行修改状态
//返回的promise执行的结果
//去判断要返回promise的状态
ret.then(resolve,reject);//立即执行。
/*
* 由于当前的处理结果 返回的是一个new Projecte
* 不知道他处理的怎么样
*
* 但是我能通过 ret.then(成功了走这,失败了走这)
* 这个返回的promise执行成功了,我这个返回的promise对象也要成功
* //调用 113行的 构造器给你的两个方法
ret.then(
value=>{
resolve(value)//修改状态
},resonal=>{
reject(resonal)//修改状态
}
* */
)
}else{
//返回的是 非Promise对象
//需要改变 返回的promise的状态--为成功
resolve(ret) // .then{throw e} 直接导致返回的promise失败
//构造器给你的两个方法,
}
}catch(e){
//第一种情况
reject(e)//修改状态 构造器给你的两个方法
}
},
onRejected:function(resonal){
//然后执行的结果====》修改返回的状态
//不需要包裹setTimeOut() 因为在执行器执行的时候
//已经包裹了一层setTimeout
//onRejected(resonal)
//拷贝
try{
const ret = onRejected(that.data)
if(ret instanceof Promise){
//返回的promise
//这个返回的promise的状态已经被修改了
//只需要指定,他往哪走
//**********************************
//ret promise实例会进行回调
//执行下面value---》 代表ret的状态为成功
//执行下面的resonal---》 代表ret的状态为失败
/*ret.then(
value=>{
resolve(value)//修改状态
},resonal=>{
reject(resonal)//修改状态
}*/
//*********************************************
//简写由来
/*
function fn(event){
}
div.onclick = function(event){
fn(event)
}
/修改
div.onclick = fn //就可以实现了传递参数的问题了
* */
//***************************************
//回调函数 传递 参数 过去,然后我再调用
//所以可以简写
ret.then(resolve,reject);
)
}else{
//返回的是 非Promise对象
//需要改变 返回的promise的状态--为成功
resolve(ret)
}
}catch(e){
//第一种情况
reject(e)
}
}
})
//以下需要返回新的promise
//新的promise 由onResolved/onRejected 返回的结果决定
}else if(that.status === 'resolved'){
//状态已经改了,必然会存放value
//that.data = value // resolved函数
/*
*1.如果在onResolved执行的过程中,抛出异常,所以将要返回的promise失败
* .then(
* value=>{
* throw 3
* }
* 2.如果onResolved执行的结果不是promise对象
* .then(
* value=>{
* return 1
* }
* 则新的promise,需要执行成功,
* 3.如果onResolved执行的结果是promise,就会根据这个promise的结果去执行 成功或者失败
*
* .then(
* value=>{
* return new Promise((resolve,reject)=>{
* //resolve()//改变为成功,status 为 resolve
* //reject()//改变为失败 status 为rejected
* })
*
* }
* )
* //根据执行的结果的promise对象进行 执行新的promise
*/
setTimeout(()=>{
try{
const ret = onResolved(that.data)
if(ret instanceof Promise){
//返回的promise
//这个返回的promise的状态已经被修改了
//只需要指定,他往哪走
//**********************************
//ret promise实例会进行回调
//执行下面value---》 代表ret的状态为成功
//执行下面的resonal---》 代表ret的状态为失败
/*ret.then(
value=>{
resolve(value)//修改状态
},resonal=>{
reject(resonal)//修改状态
}*/
//*********************************************
//简写由来
/*
function fn(event){
}
div.onclick = function(event){
fn(event)
}
/修改
div.onclick = fn //就可以实现了传递参数的问题了
* */
//***************************************
//回调函数 传递 参数 过去,然后我再调用
//所以可以简写
//返回的promise需要改变哪个状态,得根据 返回的promise的状态去执行
ret.then(resolve,reject);
)
}else{
//返回的是 非Promise对象
//需要改变 返回的promise的状态--为成功
resolve(ret)
}
}catch(e){
//第一种情况
reject(e)
}
})
}else{ //和成功的代码一致,只是修改了 onResolve------》onRejected
//rejected
//onRejected(that.data)
setTimeout(()=>{
try{
const ret = onRejected(that.data)
if(ret instanceof Promise){
//返回的promise
//这个返回的promise的状态已经被修改了
//只需要指定,他往哪走
//**********************************
//ret promise实例会进行回调
//执行下面value---》 代表ret的状态为成功
//执行下面的resonal---》 代表ret的状态为失败
/*ret.then(
value=>{
resolve(value)//修改状态
},resonal=>{
reject(resonal)//修改状态
}*/
//*********************************************
//简写由来
/*
function fn(event){
}
div.onclick = function(event){
fn(event)
}
/修改
div.onclick = fn //就可以实现了传递参数的问题了
* */
//***************************************
//回调函数 传递 参数 过去,然后我再调用
//所以可以简写
//修改转台 由ret执行的结果来确定 是成功还是失败的专题
ret.then(resolve,reject);
)
}else{
//返回的是 非Promise对象
//需要改变 返回的promise的状态--为成功
//修改状态
resolve(ret)
}
}catch(e){
//第一种情况
reject(e)
}
})
}
})
}
async await 说明
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script type="text/javascript">
/*
* async function
* 用来定义一个返回asyncFunction对象的异步函数
*
* async 函数 :async右边是函数
* 函数的返回的promise的结果由函数执行的结果决定
*
* await 表达式 : await 右边是表达式
*
*
*
*/
/*function fn1(){
return 1
}
const a = fn1()//结果为1*/
//加上async后
/*
async function fn1(){
return 1 //会进行封装,返回一个新的promise对象
}
const ret = fn1()
console.log(ret)//Promise对象*/
//async 返回值 为promise对象
//失败的promise对象
async function fn1(){
throw 3 //会进行封装,返回一个新的promise对象
}
const ret = fn1()//失败的promise对象
ret.then(
value=>{
console.log(value,'成功')
},
resonal=>{
console.log(resonal,'失败')
}
)
//失败的promise
async function fn2(){
return Promise.reject(3232)
}
const k = fn2()//失败的promise对象
k.then(
value=>{
console.log(value,'成功')
},
resonal=>{
console.log(resonal,'失败')
}
)
//延迟 失败。。。。。
async function fn3(){
return new Promise((resovle,reject)=>{
setTimeout(()=>{
reject(3232)
},3000)
})
}
const k3 = fn3()//失败的promise对象
k3.then(
value=>{
console.log(value,'成功')
},
resonal=>{
console.log(resonal,'失败')
}
)
/
function fn6(){
return Promise.resolve(3113313)
}
//await 必须在函数里面使用
//函数里面使用了await ,则函数前面必须声明async
// 通过async 声明的函数,将会 返回一个包装过的promise对象
// await 表达式
// await 函数-返回一个promise(可以自己放回,也可以使用async进行声明这个函数,则会返回包装好的promise 处理的结果)
// 不加await,则会接收promise对象
// await 普通函数====》结果就是这个普通函数
// await 普通函数()===》普通函数处理的结果
async function fn7(){
//const value = fn6()//不想.then 获取到promise处理的结果
//添加 await 就可以获得 promise处理的结果
const value = await fn6() //这个await 右边为promise
//这个结果就是promise处理之后的值
//等待 fn6执行的结果
//函数内部使用了await
//则函数必须声明为async
console.log(value) //await右边不是promise,得到的表达式就是这个值本身
const k2 = await 888
console.log(k2)
const k3 = await function(){
console.log('hello')
}
console.log(k3)//函数本身
const k5= await (function(){
console.log('hello')
})()
console.log(k5)//函数本身
}
fn7()
//await 等待一个失败的promise
function km(){
//return 34334343443443
return new Promise((resolve,reject)=>{
reject('失败咯失败咯')
})
}
(async function (){
try{
const mm = await km() //异常直接 走catch,e就是reject传入的值
//await 失败的表达式(函数执行,不返回promise)===》也会走catch
//const mm = await km
console.log(mm+'mm')
}catch(e){
console.log(e) //
}
})()
</script>
</html>