一、嘛是回调地狱

  • 多层回调函数层层嵌套,使得代码看起来很混乱
    1. var baseUrl="https://music.aityp.com/";
    2. $.ajax({
    3. url:baseUrl+"top/playlist",
    4. type:"get",
    5. data:{
    6. cat:"华语"
    7. },
    8. dataType:"json",
    9. success:res=>{
    10. var {playlists}=res;
    11. var item=playlists[0];
    12. console.log(item)
    13. $.ajax({
    14. url:`${baseUrl}playlist/detail?id=${item.id}`,
    15. type:"get",
    16. success:res=>{
    17. let id=res.playlist.trackIds[0].id;
    18. console.log(id)
    19. $.ajax({
    20. url:`${baseUrl}song/url?id=${id}`,
    21. success:res=>{
    22. console.log(res)
    23. }
    24. })
    25. }
    26. })
    27. }
    28. })

二、解决回调地狱

2-1 Peomise

promise(resolve,reject)—将函数的状态暂停/凝固,函数调用的时候不会马上触发
实现原理

我们使用promise的时候会将函数的状态暂停/凝固 ,promise函数调用的时候不会马上触发
 new Promise
1.使用new 关键字实现promise
2.promise有两种状态resolve,reject
3.promise函数不会马上触发,要通过一个then函数去触发
4.then触发的是resolve的状态,catch触发reject的状态
  resolve  --->成功   --then
  reject   --->失败   --catch
function go(){
  return new Promise((resolve,reject)=>{
    resolve(1);
    reject(2);
  })
}
go().then(res=>{
  console.log(res)
}).catch(err=>{
  console.log(err)
})
/* 回调函数是一个异步处理过程 */
var p=new Promise((resolve,reject)=>{
  resolve("success");
  rejecet("失败");
})
p.then(res=>{
  console.log(res)  //success
})
console.log("4")
//输出结果:
     4
   success

示例:

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script src="lib/http-promise.js"></script>

var baseUrl="https://music.aityp.com/";
function http(url){
    return new Promise((resolve,reject)=>{
        $.ajax({
            url:baseUrl+url,
            type:"get",
            success:res=>{
                resolve(res)
            },
            error:err=>{
                reject(err)
            }
        })
    })
}

/*使用promise之后将http请求由纵向的变为横向的了*/
http("top/playlist?cat=华语").then(res=>{
  let id=res.playlists[0].id;
  return id
}).then(res=>{
  http(`playlist/detail?id=${res}`).then(res=>{
    let id=res.playlist.trackIds[0].id;
    return id
  }).then(res=>{
    http(`song/url?id=${res}`).then(res=>{
      console.log(res)
    })
  })
})

2-2 generator

2-2-1 co

generator必须要结合co这个库来使用
引入cohttps://www.bootcdn.cn/co/

<script src="https://cdn.bootcss.com/co/4.1.0/index.js"></script>
<script>
        /*generator 必须要结合co这个库来用 */
      async  function go(x){
            return x;
        }
        co(function *(){
            var data=yield go(3);
            console.log(data);    //3
            var y=yield go(4);
            console.log(y)       //4
        })
    </script>

2-2-2 http-generator

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>
        var baseUrl="http://192.168.14.49:5000/"
        function http(url){
            return $.ajax({
                url:baseUrl+url,
                dataType:"json"
            })
        }
        function *getData(){
            var id=yield http("top/playlist");
            console.log(id)
            yield http(`playlist/detail?id=${id}`);
        }
        var res=getData();
        res.next().value.then(data=>{
            var {id,name} =data.playlists[0];
            res.next(id).value.then(res=>{
                console.log(res)
            })
        })
    </script>

2-2-3 http-generator-co

<script src="https://cdn.bootcss.com/co/4.1.0/index.js"></script>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>
        var baseUrl="http://192.168.14.49:5000/"
        function http(url){
            return $.ajax({
                url:baseUrl+url,
                dataType:"json"
            })
        }
        co(function *(){
            const data=yield http("top/playlist");
           var {id,name}=data.playlists[0];
           const detail=yield http(`playlist/detail?id=${id}`)
           console.log(detail)
        })
</script>

2-3 async/await

2-3-1 async

/*如果函数前面加上async关键字,函数会变成一个promise*/
async function go(){
  return 1
}
console.log(go())
/*通过then去执行*/
go().then(res=>{
  console.log(res)
})

async嵌套的问题

  /* await:就是跟在它后面的promise执行完毕之后才会执行下面的代码 */
        /* forEach是一个同步的 */
        async function go(){
            return "go"
        } 
        var arr=['html','css','js','vue']
        // console.log(1);
        // arr.forEach(item=>{
        //     console.log(item)
        // })
        // console.log(2)
        /* async是一个promise,不能马上触发 */
        async function test(){
            console.log(1);
            await arr.forEach(async item=>{
                var data=await go();
                console.log(data)
            })
            console.log(2) 
        }
        test()
        /* 输出结果
                1
                go(4)
                2
        */
    </script>

2-3-2 await

  1. 执行一个promise
  2. await一定要跟promise
  3. await一定要在async函数里面使用
  4. 跟在await后面的promise执行完毕之后,才会继续执行后面的参数
    <script>
     async function go(){
       return 1;
     }
     async function getRes(){
       var data=await go();
       console.log(data)
     }
     getRes()
    </script>
    

通过await可以将异步变成同步

async function go(){
  return new Promise((resolve,reject)=>{
    resolve(1);
    reject(2)
  })
}
async function getRes(){
  var data=await go();
  console.log(data);
  console.log(4)
}
getRes()
//1  4

await原生同步例子

async function go(){
  return "go"
}
var arr=['html','css','js','vue']
async function test(){
  console.log(1);
  for(let i=0;i<arr.length;i++){
    var data=await go();
    console.log(data);
  }
  console.log(2)
}
test()

2-3-3 例子

<script>
        /* 
        1.async关键字可以将一个普通函数变为promise
        2.    
     */
        async function getCat(){
            return "华语"
        }
        async function detail(){
            return "detail"
        }
        async function url(){
            return "url"
        }
        async function getRes(){
            var cat =await getCat();
            console.log(cat)
            var details=await detail();
            console.log(details);
            var Url=await url();
            console.log(Url);
        }
        getRes();
    </script>

网易云音乐接口

 <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
 <script src="lib/http.js"></script>

lib/http.js

var baseUrl="https://music.aityp.com/";
function http(url,data){
    return new Promise((resolve,reject)=>{
        $.ajax({
            url:baseUrl+url,
            type:"get",
            data,
            success: res=>{
                resolve(res)
            },
            error:err=>{
                reject(err)
            }
        })
    })
}
async function getRes(){
 var cat=await  http('top/playlist',{cat:"华语"})
            var id=cat.playlists[0].id;
            var detail=await http('playlist/detail',{id})
            var url=await http('song/url',{id:detail.playlist.trackIds[0].id})
            console.log(cat)
            console.log(detail)
            console.log(detail.playlist.trackIds[0].id)
        }
        getRes()