promise 的详解

初体验 promise

抽奖概率为30%

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
</head>
<body>
   <button>抽奖</button>
</body>
<script>
   var btn=document.querySelector("button")
   function ran(n,m){
       return Math.ceil(Math.random()*(n-m))+m
  }
   btn.onclick=()=>{
       var p = new Promise((resolve,reject)=>{
           setTimeout(()=>{
               var num=ran(0,100)
               if(num<30){
                   resolve(num)
              }else{
                   reject(num)
              }
          },1000)
      })
       p.then((value)=>{
           alert(`抽奖成功,你的号码是${value}`)
      },(reason)=>{
           alert(`没有抽中 你的幸运号码是${reason}`)
      })
  }
</script>
</html>

文件读取

var fs=require("fs");

// fs.readFile("./a.txt",(err,data)=>{
//     if(err) throw(err)
//     console.log(data.toString())
// })

let p=new Promise((resolve,reject)=>{ //声明promise就会自动允许
   fs.readFile("./a.txt",(err,data)=>{
       if(err) reject(err)
       resolve(data)
       // console.log(data.toString())
  })
})

p.then((value)=>{
   console.log(value.toString())
},(reason)=>{
   console.error(reason)
})

对Ajax的封装

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
</head>
<body>
   <button id="btn">发送Ajax</button>
</body>
<script>
   let btn=document.getElementById("btn");
   btn.addEventListener("click",function(){
       const p=new Promise((resolve,reject)=>{

           const xhr=new XMLHttpRequest();
           xhr.open("get","https://api.apiopen.top/getJoke");
           xhr.send();
           xhr.onreadystatechange=function(){
               if(xhr.readyState===4){
                   if(xhr.status>=200&&xhr.status<300){
                       resolve(xhr.response)
                  }else{
                       reject(xhr.status)
                  }
              }
          }
      });
       p.then((value)=>{
           console.log(JSON.parse(value).code);
      },(reason)=>{
           console.warn(reason)
      })
  })
   
</script>
</html>

封装fs文件操作函数

输入文件路径即可读取数据


function foo(path){
   return new Promise((resolve,reject)=>{
       require("fs").readFile(path,(err,data)=>{
           if(err) reject(err)
           resolve(data)
      })
  })
}

foo("./a.txt").then((value)=>{
   console.log(value.toString())
},(reason)=>{
   console.log(reason)
})

封装Ajax函数

输入url即可接收数据

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
</head>
<body>
   
</body>
<script>
   
   function sendAjax(url){
       return new Promise((resolve,reject)=>{
           const xhr=new XMLHttpRequest();
           xhr.responseType="json";
           xhr.open("get",url);
           xhr.send();
           xhr.onreadystatechange=function(){
               if(xhr.readyState===4){
                   if(xhr.status>=200&&xhr.status<300){
                       resolve(xhr.response)
                  }else{
                       reject(xhr.status)
                  }
              }
          }
      })
  }

   sendAjax("https://api.apiopen.top/getJoke").then((value)=>{
       console.log(value)
  },(reason)=>{
       console.warn(reason)
  })
</script>
</html>

util.promiseify

作用:传入一个错误优先的回调风格 后返回一个promise


let util=require("util")
let fs=require("fs")
// fs.readFile("",(err,data)) 回调函数err优先 并返回promise
foo=util.promisify(fs.readFile)

foo("./a.txt").then((value)=>{
   console.log(value.toString())
},(reason)=>{
   console.log(reason)
})

catch的使用

对 promise 失败进行处理

console.log(1)

let p =new Promise((resolve,reject)=>{
   reject("错误")
   console.log(2)

})
console.log(3)
p.catch((reason)=>{
   console.log(reason)
})

promise中的api的使用

resolve-Api

如果传入的值为非promise的对象 则返回状态成功 而值为传入的值

如果传入的值为promise 状态为传入的promise的状态 值为传入的promise的值

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
</head>
<body>
   
</body>
<script>
   let p=Promise.resolve("123");
   console.log(p)
   let p1=Promise.resolve(new Promise((resolve,reject)=>{
       // resolve("成功")
       reject("失败")
  }));
   console.log(p1)
   p1.catch((reason)=>{
       console.log(reason)
  })
</script>
</html>

reject-Api

不管传入什么值 返回的状态都是 失败的状态

如果传入的是非promise 则值是 传入的值

如果传入的是primise 则值是promise这个对象

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
</head>
<body>
   
</body>
<script>
   let p=Promise.reject("123")
   // 不管传入什么值返回的状态都是错误 也包括promise
   // 但是如果传入的是promise返回的值是promise对象

   console.log(p)
   let p2=Promise.reject(new Promise((resolve,reject)=>{
       resolve("成功")
  }))
   console.log(p2)

   // 处理p2的结果
   p2.catch(reason=>{
       reason.then((value)=>{
           console.log(value)
      },(reason)=>{
           console.log(reason)
      })
  })
</script>
</html>

All-api

传入一个promise的数组 如果数组里面的promise都是成功

则返回的promise 状态也是成功 若有一个失败则返回的

promise的状态是失败 值是最早那个值

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
   
</body>
<script>
  let p1=Promise.resolve("123")
  let p2=new Promise((resolve,reject)=>{
      resolve("成功")
  })
  let p3=Promise.resolve("11112")

  let result=Promise.all([p3,p1,p2])
  console.log(result)
</script>
</html>

race-Api

race英语单词为赛跑

这个api也是传入一个promise的数组 返回的promise 状态和值为第一个返回的promise [p1,p2,p3] 正常race后的返回是p1

若p1 是个定时器 则第一个返回的是p2

<!DOCTYPE html>
<html lang="en">

<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
</head>

<body>

</body>
<script>
   let p1 = new Promise((resolve, reject) => {
       setTimeout(() => {
           resolve("123")
      }, 1000)
  })
   let p2 = new Promise((resolve, reject) => {
       reject("失败")
  })
   let p3 = Promise.resolve("11112")
   let result = Promise.race([p1, p2, p3])
   console.log(result)
</script>

</html>

promise关键问题

修改promise的状态

1 就是我们熟知的 resolve--成功 reject--失败

2 就是抛出异常 throw--失败

一个 promise 指定多个成功/失败回调函数, 都会调用吗?

会同时调用

let p = new Promise((resolve,reject)=>{
       resolve("成功")
  })
   p.then(value=>{
       console.log(value)
  })
   p.then(value=>{
       alert(value)
  })

改变状态和回调函数的执行顺序

答:都有可能

let p = new Promise((resolve,reject)=>{
       resolve("成功")
  })
   p.then(value=>{

  },reason=>{

  })

这样是先改变状态

let p2 = new Promise((resolve,reject)=>{
       setTimeout(()=>{
           resolve("成功")
      },1000)
  })
   p2.then(value=>{

  },reason=>{

  })

这样是先执行回调 此类用的比较多

什么时候得到数据?

当状态改变后菜能得到数据

then的返回值

不管是resolve还是reject传下来的promise都是一样

1 如果返回(return) 是非promise对象 则返回的promise状态 成功 值为返回的 值

2 如果返回 promise对象 则返回的就是这promise 状态和值也是一样

链式调用

  let p =new Promise((resolve,reject)=>{
       resolve("成功1")
  })
   p.then(value=>{
       console.log(value)
       return new Promise((resolve,reject)=>{
           resolve("成功2")
      })
  }).then(value=>{
       console.log(value)
       return false
  }).then(value=>{
       console.log(value)
  })

异常穿透

即不用每次链式调用时都需要写 reason

只要在最后一个链式调用使用catch即可处理之前的 reject

 let p =new Promise((resolve,reject)=>{
       // resolve("成功1")
       reject("错误")
  })


   // 只要在最后一个catch即可捕获第一个异常
   p.then(value=>{
       console.log(value)
       // throw "粗我"
  }).then(value=>{
       console.log("123")
  }).catch(reason=>{
       console.log(reason)
  })

中断链式调用

只要在想要中断的地方返回一个pending即可

new Promise(()=>{})

let p =new Promise((resolve,reject)=>{
       resolve("成功1")
  })


   p.then(value=>{
       console.log(value)
       return new Promise(()=>{})  //new promise(()=>{}) 返回一个pending即可终止链式调用
  }).then(value=>{
       console.log("123")
  }).catch(reason=>{
       console.log(reason)
  })

 

posted @ 2021-05-26 23:28  彡心如止水彡  阅读(140)  评论(0)    收藏  举报