Promise异步思想及解决回调地狱(async+await)

我想点一份火锅和一杯奶茶,但是火锅实在太辣了,必须奶茶先到我才敢吃火锅,所以我希望配送顺序是奶茶先到火锅紧接着再到,如何解决这个问题呢?

 function tea(fn){
          setTimeout(() => {
          fn("奶茶到了")
          }, 2000);
          }
          function hot(fn){
          setTimeout(() => {
          fn("火锅到了")
          }, 1000);
          }
          tea(function(data){
          console.log(data);
          hot(function(data){
          console.log(data);
          })
          })

在计时器里面我们无法将参数传递出去,只能通过回调函数,fn就是一个回调函数,调用的时候通过tea(function(){xx})传入一个函数作为实参。为了解决能实现我想要的配送顺序,只有在tea()执行完成也就是奶茶配送到了以后hot()才会执行火锅才会送达。(我要拿到上一个函数返回的结果才能执行下一个函数)

什么是回调地狱

那么如果有多个这样的需求,我要等奶茶到了火锅才到,火锅到了食材才到,食材到了才能清洗,清洗完才能切.....那么代码将会变成这样:

tea(function(data){
    console.log(data);
        hot(function(data){
          console.log(data);
            buy(function(data){
               console.log(data);
                  wash(function(data){
                     console.log(data);
                        cut(function(data){
                            console.log(data);
                    })
                })
            })
        })
    })

代码的业务需求仅仅只是用console.log来替代,就已经是一个非常杂乱的状态了,让代码后期难以维护,这就是所谓的回调地狱。

Promise函数

如何解决这样的问题呢,promise给我们带来了解决方案:

 let tea = new Promise((resolve,reject) =>{
              setTimeout(() =>{
                  let flag = true;
                  if(flag){
                    resolve("奶茶到了")
                  }else{
                    reject("奶茶还没到")
                  }
              },2000)
          })

          let hot = new Promise((resolve,reject) =>{
              setTimeout(() =>{
                  let flag = true;
                  if(flag){
                    resolve("火锅到了")
                  }else{
                    reject("奶茶还没到")
                  }
              },2000)
          })

          tea.then((data) =>{
              console.log(data);
              return hot;
          }).then(() =>{
              console.log(data);
          }).catch((err) =>{          
              console.log(err);
          })

resolve直接将值传递给then方法,reject将值传递给catch,这种方法虽然代码量比上一种会大,但是.then.then这种顺序执行的代码还是比较直观并且易于维护。但是这还是用了很多回调函数啊,下面这种就能很好的解决这个问题。

async/await优化

 let tea = new Promise((resolve,reject) =>{
              setTimeout(() =>{
                  let flag = true;
                  if(flag){
                    resolve("奶茶到了")
                  }else{
                    reject("奶茶还没到")
                  }
              },2000)
          })

          let hot = new Promise((resolve,reject) =>{
              setTimeout(() =>{
                  let flag = true;
                  if(flag){
                    resolve("火锅到了")
                  }else{
                    reject("奶茶还没到")
                  }
              },2000)
          })

   
          async function asy(){
              let Tea = await tea;
              console.log(Tea);
              let Hot = await hot;
              console.log(Hot);
          }
          asy();
          

Promise 通过 then 链来解决多层回调的问题,现在又用 async/await 来进一步优化它

有没有觉得现在代码可维护性变强了,更加直观了!

await是async函数里面的一个关键字,用法是await加一个promise对象(await Promise),字面意思是等待。

如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。

看到上面的阻塞一词,其实不用担心,因为这就是 await 必须用在 async 函数中的原因。async 函数调用不会造成阻塞,它内部所有的阻塞都被封装在一个 Promise 对象中异步执行。

通过一个奶茶火锅的小故事延伸到异步函数,再到用promise函数解决回调地狱,再然后用async/await进一步优化它。

猜你喜欢

转载自blog.csdn.net/qq_20495901/article/details/123430597