详解Promise和Async用法

目录

一.Promise的概念

二.回调地狱

三.Promise的基本用法

四.用Promise来解决回调地狱

五.Async await基本用法

概念

六.Promise.all.race.any的用法

一.Promise的概念

Promise 是 JavaScript 中的一种异步编程解决方案。它用于处理异步操作,并提供了一种更优雅和可靠的方式来处理异步代码。Promise 可以看作是一个代表了异步操作最终完成或失败的对象。

Promise 有三种状态:pending(进行中)、fulfilled(已完成)和 rejected(已拒绝)。当一个 Promise 对象被创建时,它的初始状态是 pending。当异步操作成功完成时,Promise 对象的状态会变为 fulfilled,并且会调用 resolve 方法来传递解析值。当异步操作失败时,Promise 对象的状态会变为 rejected,并且会调用 reject 方法来传递拒绝原因。

除了 then 方法,Promise 还提供了其他一些方法,例如 catch 方法用于捕获和处理异步操作中的错误,以及 finally 方法用于在 Promise 链的最后执行一些操作,无论 Promise 是成功还是失败。

使用 Promise 可以避免回调地狱的问题,使异步代码更易于理解和维护。通过合理地使用 Promise,可以实现更清晰、可读性更高的异步代码。

二.回调地狱

既然使用 Promise 可以避免回调地狱的问题,那就举个例子什么是回调地狱

如果在回调函数中再传入一个函数,就会出现一个嵌套结构如此层层嵌套回调就会形成回调地狱。

什么时候会用到在回调函数中再传入一个函数呢

function sendRequest(url, callback) {
  // 模拟发送网络请求的异步操作
  setTimeout(function() {
    const response = "请求成功";
    const error = null;
    callback(error, response);
  }, 1000);
}
 sendRequest("https://example.com/api", function(error, response) {
  if (error) {
    console.log("请求失败:" + error);
  } else {
    console.log("请求成功:" + response);
     sendRequest("https://example.com/api2", function(error, response) {
      if (error) {
        console.log("请求失败:" + error);
      } else {
        console.log("请求成功:" + response);
         sendRequest("https://example.com/api3", function(error, response) {
          if (error) {
            console.log("请求失败:" + error);
          } else {
            console.log("请求成功:" + response);
          }
        });
      }
    });
  }
});

当我们有多个网络请求,第二个网络请求需要在第一个网路请求成功后再执行,第三个网络请求需要在第二个网络请求成功后执行的时候,就需要嵌套,而嵌套过多,使代码难以读解,就形成了回调地狱

这是个简洁一点的回调地狱-模拟异步代码

我想让打印完开始再执行打印进行,打印完进行再执行打印结束

 setTimeout(function(){
            console.log("开始")
            setTimeout(function(){
                console.log("进行")
                setTimeout(function(){
                    console.log("结束")
                },1000)
            },800)
        },1500)

而Promise就可以解决这样的回调地狱!

三.Promise的基本用法

使用 Promise 构造函数来创建一个 Promise 对象。构造函数接收一个带有两个参数的回调函数作为参数,这两个参数分别是 resolve 和 reject。resolve 用于将 Promise 对象的状态从 pending 变为 fulfilled,reject 则用于将状态从 pending 变为 rejected。

const p=new Promise(function(resolve,reject){
        //延时器只是为了模拟异步操作
        setTimeout(function(){
          1+1===2//判断1+1等于2吗
          ?resolve("成功了")//异步操作成功调用resolve,并给成功的操作传了一个数据-成功了
          :reject("失败了")//异步操作失败调用reject,并给失败的操作传了一个数据-失败了
        },2000)
    })
    //p现在是一个promise实例,then的意思是:然后||接下来
    //p.then代表,p执行完后呢||p执行完接下来干什么
    //p.then()里面要写一个回调函数,回调函数的参数就是成功传来的数据
    p.then(res=>{//这里的参数是调用resolve传来的数据
      console.log(res)
    })
    //p.catch表示失败,与then一样,只是一个表示成功,一个表示失败
    p.catch(res=>{//这里的参数是调用reject传来的数据
      console.log(res)
    })

四.用Promise来解决回调地狱

我们还用刚才那个简洁一些的回调地狱案例,现在把他用Promise改写

         //用promise链式调用解决回调地狱
        //实例化
        const p=new Promise(function(resolve,reject){
            setTimeout(function(){resolve("开始")},900)//900ms秒后执行then
        })

        //这个.then是p的then
        .then(res=>{
            console.log("我是900ms后执行的"+res)
            //返回一个promise,这样.then也是一个promise实例化对象
            return new Promise(function(resolve,reject){
            setTimeout(function(){resolve("进行")},700)//700ms后执行,下一个then
            })
        })

        // 这个.then是上个then的then,在上个then中返回了一个promise,上个then也是一个promise对象
        // 也就是说这个then是p.then的then
        .then(res=>{
            console.log("我是700ms后执行的"+res)
            return new Promise(function(resolve,reject){
            setTimeout(function(){resolve("结束")},500)//500ms后执行,下一个then
            })
        })

        //上个.then里也返回了promise对象,所以也是一个promise对象
        // 这个.then是上个then的
        .then(res=>{
            console.log("我是500ms后执行的"+res)
        })

上面的代码为了让小白看懂,加些注释有些凌乱,我们来封装一下

        //上面的代码每一次都return了一相同的promise对象,我们可以把他封装一下,减少代码量
        function timeout(str,ms){
            return  new Promise(function(resolve,reject){
            setTimeout(function(){resolve(str)},ms)
        })
        };

        timeout("开始",1000)

        .then(res=>{
            console.log(res)
            return timeout("进行",1000)
        })
        .then(res=>{
            console.log(res)
            return timeout("结束",1000)
        })
        .then((res=>{
            console.log(res)
        }))

五.Async await基本用法

概念

Async 是 JavaScript 中用于处理异步操作的关键字。它通常与 await 关键字一起使用,以更简洁和可读性更高的方式编写异步代码。 Async/await 是基于 Promise 的一种语法糖,它使得异步代码的编写和理解更加直观和顺序化

        //在前面的例子里,使用promise的链式调用,每个。then都返回了一个promise对象
        //连续的链式调用使代码并不直观,async可以将异步代码写成类似于同步代码的结构,
        //使代码更易读,易懂.不再需要嵌套的回调函数或者链式的 Promise调用,减少了代码的复杂性。
        
        //定义三个带有返回promise对象的函数
        function p1(){
            return new Promise(function(resolve,reject){
            setTimeout(function(){resolve("开始")},1000)//900ms秒后执行then
        })
        }

        function p2(){
            return new Promise(function(resolve,reject){
            setTimeout(function(){resolve("进行")},700)//900ms秒后执行then
            })
        }

        function p3(){
            return new Promise(function(resolve,reject){
            setTimeout(function(){resolve("结束")},500)//900ms秒后执行then
        })
        }
        //async来声明timeout是个异步函数,await后面跟等待的对象
        async function timeout(){
            let a1=await p1()
            console.log(a1)
            let a2=await p2()
            console.log(a2)
            let a3=await p3()
            console.log(a3)
        }
        timeout()

async/await 是建立在 Promise 的基础上的语法糖,它并不是完全取代 Promise,而是提供了一种更优雅、更易用的方式来处理异步操作。在实际使用中,仍然需要理解Promise 的基本概念和原理。

再接着写一个案例

      function p1(num, ms) {
        return new Promise(function (resolve, reject) {
          setTimeout(function () {
            1+1===num
            ?resolve("正确")
            :reject("错误")
          }, ms);
        });
      }


      function p2(num){
        return new Promise(function(resolve,reject){
          setTimeout(function(){
            3+2===num
          ?console.log("正确")
          :console.log("错误")
          },800)
        })
      }

      //await后面只有写promise才会等待
      async function timeout() {
        let qwe= await p1(2, 1000);//第一个异步里的代码有成功返回的数据,
        console.log(qwe)
                await p2(4)//第二个异步里的代码是直接打印
      }
      timeout();

六.Promise.all.race.any的用法

all

 const p1=new Promise(function(resolve,reject){
         setTimeout(function(){
            1+1==3
            ?resolve("p1正确")//如果成功调用resolve
            :reject("我是p1的错误信息")//失败调用reject
         },200)
       })
   
       const p2=new Promise(function(resolve,reject){
         setTimeout(function(){
            1+1==2
            ?resolve("p2正确")//如果成功调用resolve
            :reject("我是p2的错误信息")//失败调用reject
         },5000)
       })

//如果所有实例都成功会执行then。如果有一个失败则直接返回执行catch
       Promise.all([p1,p2])//如果p1和p2都成功,才会执行Promise.all .then的代码
       .then(res=>{
        console.log(res,"p1,p2都成功了")
       })
       .catch(error=>{
        console.error("错误",error)
       })

     //封装一下
        function p(num){
          return new Promise(function(resolve,reject){
            3+2==num
            ?resolve("成功")
            :reject("失败")
          });
        }

      async function asy(){
        try{
          let p1=await Promise.all([p(1),p(5)])
          console.log(p1)
        }catch(error){
          console.error(error)
        }
      }
        asy()

race和any

 const p1=new Promise(function(resolve,reject){
         setTimeout(function(){
            1+1==3
            ?resolve("p1正确")//如果成功调用resolve
            :reject("我是p1的错误信息")//失败调用reject
         },3000)
       })

       const p2=new Promise(function(resolve,reject){
         setTimeout(function(){
            1+1==3
            ?resolve("p2正确")//如果成功调用resolve
            :reject("我是p2的错误信息")//失败调用reject
         },1000)
       })

//race是promise实例中只要有一个状态发生改变就执行then/catch方法,以耗时短的为准
//后面的promise实例不再执行
       Promise.race([p1,p2])
       .then(res=>{
        console.log(res)
       })
       .catch(res=>{
        console.log(res)
       })

//any 是碰到promise实例中第一个发生成功状态(resolve)时执行then方法,后面不再执行
//假如第一次发生失败,则看第二个,第二个还失败就看第三个,如果遇到成功则直接执行then
//如果全部失败,则会抛出AggregateError:All promises were rejected
        Promise.any([p1,p2])
       .then(res=>{
        console.log(res)
       })
       .catch(res=>{
        console.error(res)
       })

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Promiseasync/await都是用于处理JavaScript中的异步操作的工具。它们可以帮助我们更简洁地编写异步代码,并使其更易于阅读和维护。 Promise是一种表示异步操作的对象。它可以有三种状态:Pending(进行中)、Fulfilled(已完成)和Rejected(已拒绝)。当一个Promise对象的状态改变时,它会调用相应的回调函数。 我们可以使用Promise来处理异步操作。通过调用Promise的构造函数并传入一个执行器函数,我们可以创建一个新的Promise对象。执行器函数接受两个参数:resolve和reject。当异步操作成功时,我们可以调用resolve函数将Promise的状态设置为Fulfilled,并传递一个值作为结果。当异步操作失败时,我们可以调用reject函数将Promise的状态设置为Rejected,并传递一个错误对象。 我们可以使用Promise的then方法来处理已完成状态的Promise。then方法接受两个回调函数作为参数:第一个回调函数在Promise成功时被调用,第二个回调函数在Promise失败时被调用。 同时,我们可以使用Promise的catch方法来处理已拒绝状态的Promise。catch方法接受一个回调函数作为参数,该回调函数在Promise被拒绝时被调用。 async/await是基于Promise的语法糖,使异步代码更像同步代码。async函数是一个返回Promise对象的函数,其中使用了await关键字来暂停函数的执行,直到Promise解决(Fulfilled)或拒绝(Rejected)。 在使用async/await时,我们可以使用try/catch语句来捕获Promise中的错误。在try块中,我们可以使用await关键字来等待一个Promise的解决或拒绝。如果Promise被解决,则await表达式将返回解决的值;如果Promise被拒绝,则抛出一个错误对象,可以使用catch块捕获该错误。 总结一下,Promise是一种用于处理异步操作的对象,它有三种状态:进行中、已完成和已拒绝。我们可以使用Promise的then和catch方法来处理已完成和已拒绝状态的Promise。而async/await是基于Promise的语法糖,使异步代码更像同步代码。通过使用async函数和await关键字,我们可以以更简洁的方式编写异步代码,并使用try/catch语句来处理错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值