promise专题05(完结)-自定义promise之resolve、reject、all、race封装,then的异步执行,async,await,async结合await发送ajax请求

1、resolve方法封装

具体代码:

Promise.resolve = function (value) {
  //返回promise对象
  return new Promise((resolve, reject) => {
    if (value instanceof Promise) {
      value.then(value => {
        resolve(value)
      }, (reason) => {
        reject(reason)
      })
    }else {
      resolve(value)
    }
  })
}
2、reject方法封装
//添加promise的reject静态方法
Promise.reject=function(reason){
  //返回promise对象
  return new Promise((resolve,reject)=>{
    reject(reason)
  })
}

以上两例的全部代码

//相当于重写promise
function Promise(excutor){
  //添加属性
  this.PromiseState='pending'
  this.PromiseResult=''

  //在这里保存一个callback属性用来存放onResolved和onRejected方法
  this.callbacks=[]
  const that=this


  //同步调用执行器函数
  function resolve (data) {
    if (that.PromiseState!=='pending'){
      return
    }
    //修改对象的状态。promiseState
    that.PromiseState='fulfilled'
    //设置对象结果值promiseReuslt
     that.PromiseResult=data
    //异步状态下执行成功的回调函数(这里有点回归的意思)
    that.callbacks.forEach(item=>{
      item.onResolved(data)
    })
  }
  function reject (data) {
    if (that.PromiseState!=='pending'){
      return
    }
    that.PromiseState='rejected'
    that.PromiseResult=data
    //异步状态下执行失败的回调函数
    that.callbacks.forEach(item=>{
      item.onRejected(data)
    })
  }
  //这里要执行这个执行器函数
  try{
    excutor(resolve,reject)
  }
  catch (e) {
    reject(e)//
  }


}

Promise.prototype.then=function(onResolved,onRejected){
  const that=this
  //做异常穿透要判断回调参数
  if (typeof onRejected !=='function'){
    onRejected=(reason)=>{
      throw reason
    }
  }

  if (typeof onResolved !=='function'){
    onResolved=(value)=>{
      return value
    }
  }

  return new Promise((resolve,reject)=>{
    //封装函数
    function callback (type) {
      //获取回调函数的执行结果
      let result=type(that.PromiseResult)
      if (result instanceof  Promise){
        //如果是Promise类型的对象
        result.then(value=>{
          resolve(value)
        },reason => {
          reject(reason)
        })
      }else{
        //结果对象设为成功
        resolve(result)
      }
    }
    try{
      //调用回到函数,需要做对this.PromiseState做条件判断
      if (this.PromiseState=='fulfilled'){
        callback(onResolved)
      }
      if (this.PromiseState=='rejected'){
        callback(onRejected)

      }
      //异步状态下这里先执行
      if (this.PromiseState=='pending'){
        //把两个函数存储到callback属性上去
        //考虑到多次使用then,因此存储以push的方式push到数组中去
        this.callbacks.push({
          onResolved:function(){
            try{
              callback(onResolved)
            }catch (e) {
              reject(e)
            }

        },
          onRejected:function () {
            try{
              callback(onRejected)
            }catch (e) {
              reject(e)
            }

          }
        })
      }
    }
    catch (e) {
      reject(e)
    }

  })


}
//添加promise的catch方法
Promise.prototype.catch=function (onRejected) {
    return this.then(undefined,onRejected)
}

//添加promise的resolve静态方法
Promise.resolve=function (value) {
  //返回promise对象
  return new Promise((resolve,reject)=>{
    if (value instanceof Promise){
      value.then(value => {
        resolve(value)
      },(reason)=>{
        reject(reason)
      })
    }
  })
}
//添加promise的reject静态方法
Promise.reject=function(reason){
  //返回promise对象
  return new Promise((resolve,reject)=>{
    reject(reason)
  })
}

3、all方法封装
  • all方法所有promise成功才能成功,所以需要遍历参数数组
  • 在每一个参数数组元素(promise)执行then的结果,执行计数器加一,并将结果添加到结果数组中
  • 到了计数器和参数数组长度一致的时候,则返回那个结果数组
//添加promise的all静态方法
Promise.all = function (promises) {
  return new Promise((resolve, reject) => {
    //设置一个计数变量
    let count = 0
    //设置接收返回的promise对象数组
    let promisesArry = []
    for (let i = 0; i < promises.length; i++) {
      //遍历每一个promises参数中的promise对象
      promises[i].then((value) => {
        //得知对象成功则计数器加一
        count++
        //把处理结果值依次放到返回的promise对象数组中
        promisesArry[i] = value
        //如果每次都可以返回则循环计数器将最终等于参数数组的长度
        if (count === promises.length) {
          //最后一次性resolve完整个promise数组
          resolve(promisesArry)
        }

      }, (reason) => {
        //只要一旦计入到一个reject,整体就返回reason了
        reject(reason)
      })
    }
  })
}

脚本中执行

<script>

  $('#send_ajax').click(function(){
      let promise1=new Promise((resolve,reject)=>{
      		//resolve(ok)
          setTimeout(()=>{
            resolve('ok')
          },1000)
      })

    // let promise2=new Promise.resolve('成功')
    // let promise3=new Promise.resolve('success')
    let promise2=new Promise((resolve,reject)=>{
      resolve('成功')
    })
    let promise3=new Promise((resolve,reject)=>{
      resolve('succes')
    })
    let result=Promise.all([promise1,promise2,promise3])
    console.log(result)
  })
</script>

结果:
非异步状态下:
在这里插入图片描述

异步状态下:
在这里插入图片描述

4、race方法封装
  • 先返回成功就全部成功,先返回失败就全部失败
  • 由于异步处理,先执行同步代码,所以race的结果肯定是看第一条同步代码的返回值
  • 如果是同步处理,则看第一条同步代码的返回值,所以,异步处理结果一般来说不影响race的执行结果
//添加promise的race静态方法
Promise.race=function (promises) {
  return new Promise((resolve,reject)=>{
    for (let i=0; i<promises.length;i++){
      promises[i].then((value)=>{
        resolve(value)
      },(reason)=>{
        reject(reason)
      })
    }
  })

}

执行代码

<script>

  $('#send_ajax').click(function(){
      let promise1=new Promise((resolve,reject)=>{
      	// reject('fail')
        setTimeout(()=>{
          reject('fail')
        },1000)

      })


    let promise2=new Promise.resolve('成功')
    let promise3=new Promise((resolve,reject)=>{
      resolve('succes')
    })
    let result=Promise.race([promise1,promise2,promise3])
    console.log(result)
  })
</script>

结果:
异步代码情形下
在这里插入图片描述
同步代码情形下
在这里插入图片描述

5、then方法回调的异步执行

then方法修改这里

 //调用回到函数,需要做对this.PromiseState做条件判断
      if (this.PromiseState == 'fulfilled') {
        //异步执行加定时器
        setTimeout(()=>{
          callback(onResolved)
        })
      }
      if (this.PromiseState == 'rejected') {
        setTimeout(()=>{
          callback(onRejected)
        })
      }

主要是在then方法里修改,这里是then方法

Promise.prototype.then = function (onResolved, onRejected) {
  const that = this
  //做异常穿透要判断回调参数
  if (typeof onRejected !== 'function') {
    onRejected = (reason) => {
      throw reason
    }
  }

  if (typeof onResolved !== 'function') {
    onResolved = (value) => {
      return value
    }
  }

  return new Promise((resolve, reject) => {
    //封装函数
    function callback (type) {
      //获取回调函数的执行结果
      let result = type(that.PromiseResult)
      if (result instanceof Promise) {
        //如果是Promise类型的对象
        result.then(value => {
          resolve(value)
        }, reason => {
          reject(reason)
        })
      } else {
        //结果对象设为成功
        resolve(result)
      }
    }

    try {
      //调用回到函数,需要做对this.PromiseState做条件判断
      if (this.PromiseState == 'fulfilled') {
        setTimeout(()=>{

          callback(onResolved)

        })
      }
      if (this.PromiseState == 'rejected') {
        callback(onRejected)

      }
      //异步状态下这里先执行
      if (this.PromiseState == 'pending') {
        //把两个函数存储到callback属性上去
        //考虑到多次使用then,因此存储以push的方式push到数组中去
        this.callbacks.push({
          onResolved: function () {
            try {
              callback(onResolved)
            } catch (e) {
              reject(e)
            }

          },
          onRejected: function () {
            try {
              callback(onRejected)
            } catch (e) {
              reject(e)
            }

          }
        })
      }
    } catch (e) {
      reject(e)
    }

  })

}

此外在resolve和reject里面也要调用一下setimeout方法

  //同步调用执行器函数
  function resolve (data) {
    if (that.PromiseState !== 'pending') {
      return
    }
    //修改对象的状态。promiseState
    that.PromiseState = 'fulfilled'
    //设置对象结果值promiseReuslt
    that.PromiseResult = data
    
    setTimeout(()=>{
      //异步状态下执行成功的回调函数(这里有点回归的意思)
      that.callbacks.forEach(item => {
        item.onResolved(data)
      })
    })
    
    
  }

  function reject (data) {
    if (that.PromiseState !== 'pending') {
      return
    }
    that.PromiseState = 'rejected'
    that.PromiseResult = data
    setTimeout(()=>{
      //异步状态下执行失败的回调函数
      that.callbacks.forEach(item => {
        item.onRejected(data)
      })
    })
    
  }

执行代码:

<script>

  $('#send_ajax').click(function(){
    let promise1=new Promise((resolve,reject)=>{
        resolve('ok')
        console.log(111)
    })

    promise1.then(value=>{
      //console.log(value)
      console.log(2222)
    })

    console.log(333)
  })
</script>

结果
在这里插入图片描述
最终的自定义Promise包为:

//相当于重写promise
function Promise (excutor) {
  //添加属性
  this.PromiseState = 'pending'
  this.PromiseResult = ''

  //在这里保存一个callback属性用来存放onResolved和onRejected方法
  this.callbacks = []
  const that = this

  //同步调用执行器函数
  function resolve (data) {
    if (that.PromiseState !== 'pending') {
      return
    }
    //修改对象的状态。promiseState
    that.PromiseState = 'fulfilled'
    //设置对象结果值promiseReuslt
    that.PromiseResult = data

    setTimeout(()=>{
      //异步状态下执行成功的回调函数(这里有点回归的意思)
      that.callbacks.forEach(item => {
        item.onResolved(data)
      })
    })


  }

  function reject (data) {
    if (that.PromiseState !== 'pending') {
      return
    }
    that.PromiseState = 'rejected'
    that.PromiseResult = data
    setTimeout(()=>{
      //异步状态下执行失败的回调函数
      that.callbacks.forEach(item => {
        item.onRejected(data)
      })
    })

  }

  //这里要执行这个执行器函数
  try {
    excutor(resolve, reject)
  } catch (e) {
    reject(e)//
  }

}

Promise.prototype.then = function (onResolved, onRejected) {
  const that = this
  //做异常穿透要判断回调参数
  if (typeof onRejected !== 'function') {
    onRejected = (reason) => {
      throw reason
    }
  }

  if (typeof onResolved !== 'function') {
    onResolved = (value) => {
      return value
    }
  }

  return new Promise((resolve, reject) => {
    //封装函数
    function callback (type) {
      //获取回调函数的执行结果
      let result = type(that.PromiseResult)
      if (result instanceof Promise) {
        //如果是Promise类型的对象
        result.then(value => {
          resolve(value)
        }, reason => {
          reject(reason)
        })
      } else {
        //结果对象设为成功
        resolve(result)
      }
    }

    try {
      //调用回到函数,需要做对this.PromiseState做条件判断
      if (this.PromiseState == 'fulfilled') {
        //异步执行加定时器
        setTimeout(()=>{
          callback(onResolved)
        })
      }
      if (this.PromiseState == 'rejected') {
        setTimeout(()=>{
          callback(onRejected)
        })
      }
      //异步状态下这里先执行
      if (this.PromiseState == 'pending') {
        //把两个函数存储到callback属性上去
        //考虑到多次使用then,因此存储以push的方式push到数组中去
        this.callbacks.push({
          onResolved: function () {
            try {
              callback(onResolved)
            } catch (e) {
              reject(e)
            }

          },
          onRejected: function () {
            try {
              callback(onRejected)
            } catch (e) {
              reject(e)
            }

          }
        })
      }
    } catch (e) {
      reject(e)
    }

  })

}
//添加promise的catch方法
Promise.prototype.catch = function (onRejected) {
  return this.then(undefined, onRejected)
}

//添加promise的resolve静态方法
Promise.resolve = function (value) {
  //返回promise对象
  return new Promise((resolve, reject) => {
    if (value instanceof Promise) {
      value.then(value => {
        resolve(value)
      }, (reason) => {
        reject(reason)
      })
    }else {
      resolve(value)
    }
  })
}
//添加promise的reject静态方法
Promise.reject = function (reason) {
  //返回promise对象
  return new Promise((resolve, reject) => {
    reject(reason)
  })
}

//添加promise的all静态方法
Promise.all = function (promises) {
  return new Promise((resolve, reject) => {
    //设置一个计数变量
    let count = 0
    //设置接收返回的promise对象数组
    let promisesArry = []
    for (let i = 0; i < promises.length; i++) {
      //遍历每一个promises参数中的promise对象
      promises[i].then((value) => {
        //得知对象成功则计数器加一
        count++
        //把处理结果值依次放到返回的promise对象数组中
        promisesArry[i] = value
        //如果每次都可以返回则循环计数器将最终等于参数数组的长度
        if (count === promises.length) {
          //最后一次性resolve完整个promise数组
          resolve(promisesArry)
        }

      }, (reason) => {
        //只要一旦计入到一个reject,整体就返回reason了
        reject(reason)
      })
    }
  })
}
//添加promise的race静态方法
Promise.race=function (promises) {
  return new Promise((resolve,reject)=>{
    for (let i=0; i<promises.length;i++){
      promises[i].then((value)=>{
        resolve(value)
      },(reason)=>{
        reject(reason)
      })
    }
  })

}

6、async函数
  • 函数的返回值为promise对象
  • promise对象的结果由async函数的返回值决定
async  function main () {
      //如果返回值是一个非promise对象
      //return 333
      //如果返回值是一个promise对象,则函数返回的对象就返回的promise对象的返回值
      return new Promise((resolve,reject)=>{
        //resolve('成功')
        reject('失败')
      })

    }

    let result=main()
    console.log(result)
7、await表达式
  • await右侧的表达式一般为promise对象,但也可以是其他的值
  • 如果表达式是promise对象,await返回的是promise成功的值
  • 如果表达式是其他值,则直接将此值作为await的返回值
  • await必须写在async函数中,但async函数中可以没有await
  • 如果await的promise失败了,就会抛出异常,需要通过try…catch捕获处理
<script>

  $('#send_ajax').click(function(){

    async  function main () {
      let p=new Promise((resolve ,reject)=>{
        reject('fail')
      })
      //1、右侧为promise的情况
      //return await p
      //2、右侧为其他数据的情形
      //return await 111
      //3、右侧promise为失败的状态
      try{
        let result=await p
        return result
      }catch (e) {
        return e
      }


    }

    let result=main()
    console.log(result)
  })
</script>
8、async结合await

传统写法(有回调地狱):

const fs =require('fs')

let str=fs.readFile('../public/async1.txt',(err1,data1)=>{
  if (err1) throw err1
  fs.readFile('../public/async2.txt',(err2,data2)=>{
    if (err2) throw err2
    fs.readFile('../public/async3.txt',(err3,data3)=>{
      if (err3) throw err3
      console.log(data1+data2+data3)
    })
  })
})

aysnc写法:

const fs =require('fs')
//导入util模块
const util=require('util')
//利用util的promisify将fs.readFile转化为
const mineReadFile=util.promisify(fs.readFile)
async function mytest(){
  let data1=await mineReadFile('../public/async1.txt')
  let data2=await mineReadFile('../public/async2.txt')
  let data3=await mineReadFile('../public/async3.txt')

  console.log(data1+data2+data3)

}

mytest()


9、async结合await发送ajax请求
<script>
//未来这个函数可以使用axios进行封装
  function sendAjax(url) {
    const promise = new Promise((resolve, reject) => {
      $.ajax({
        url: url,
        type: 'GET',
        success (msg) {
          if (msg.status) {
            resolve(msg)
          } else {
            reject('请求失败')
          }
        }
      })
    })

    promise.then((value) => {
      console.log(value.data)
    }, (reason) => {
      console.log(resolve)
    })
  }

  $('#send_ajax').click(async function(){
    let url='http://localhost:3000/test'
    const result=await sendAjax(url)
    console.log(result)

  })


</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值