Promise,模拟axios

311 阅读2分钟

1,基础语法

let p = new Promise((resolve,reject) => {
    resolve('成功')//resolve和reject只执行一个
    reject('失败')
})
//只要new除一个Promise实例对象,这个实例对象就可以使用.then(调用resolve时)或者.catch(调用reject时)方法
p.then(res => {
    console.log(res)
})
.catch(err => {
    console.log(err)
})
.finally(res => { //不管执行了reject或者resolve都会执行finally,但是reject和resolve都不执行,finally也不执行
    console.log(res)
})

2,注意事项

  1. Promise对象本身是同步的,里面的代码也是同步的,当执行了resolve或者reject后的.then和.catch函数是异步的
  2. 什么时候调用resolve什么时候就执行then里的函数,什么时候调用reject什么时候就执行catch里的函数,resolv

3,使用Promise模拟axios

 function axios(obj){ //obj接收将需要发送请求的参数(method,url)
      // 返回一个promise对象,这样axios调用时就可以.then和.catch了
      return new Promise((resolve,reject) => {
        // 创建一个xhr实例
        let xhr = new XMLHttpRequest()
        // 将obj里的url和method给到xhr.open()发送请求
        xhr.open(obj.method,obj.url)
        // 发送
        xhr.send()

        // 监听onreadystatechange的变化
        xhr.onreadystatechange = function(){
          // 当xhr.readyState的值等于4时说明请求回来了
          if(xhr.readyState === 4){
            // 判断xhr.status状态码是否在200-300间,是的话就说明发送请求成功,
            // 就调用resolve函数并把请求回来的数据xhr.response传给.then()
            if(xhr.status >= 200 && xhr.status <300){
              resolve(JSON.parse(xhr.response))
            }else {
              // 失败就调用reject函数,并把失败的参数传给.catch
              reject('失败')
            }
          }
        }
      })

    }
  //使用axios
  axios({
      method:'get',
      url:'xxx'
  })

4,链式调用

promise链式调用可以解决回调地狱的问题

let p = new Promise((resolve,reject) => {
      setTimeout(function(){
        resolve('成功')
      },2000)
    })

    //.then()里面的这个函数res => {}会自己在内部return 一个Promise对象,所以后面又可以接着.then或者.catch
    p.then(res => {
      console.log(res);
      console.log(1);
      // .then()内部相当于这样
      return new Promise((resolve,reject) => {
        resolve('成功')
      })
      //每次请求成功之后就把当前的请求return出去,return出去的axios实际上又是一个promise
      //下一次.then接收到的res就是这次return出去的promise返回的结果
      return axios({
        method:'get',
        url:'http://www.liulongbin.top:3006/api/getbooks'
      })
    }).then(res => {  //这个.then是前一个.then返回的一个Promise的
      console.log(res);
      console.log(2);
      return axios({
        method:'get',
        url:'http://www.liulongbin.top:3006/api/getbooks'
      })
    }).then(res => {
      console.log(res);
      console.log(3);
     return axios({
        method:'get',
        url:'http://www.liulongbin.top:3006/api/getbooks'
      })
    }).then(res => {
      console.log(res);
      console.log(4);
    })