一、嘛是回调地狱
- 多层回调函数层层嵌套,使得代码看起来很混乱
var baseUrl="https://music.aityp.com/";
$.ajax({
url:baseUrl+"top/playlist",
type:"get",
data:{
cat:"华语"
},
dataType:"json",
success:res=>{
var {playlists}=res;
var item=playlists[0];
console.log(item)
$.ajax({
url:`${baseUrl}playlist/detail?id=${item.id}`,
type:"get",
success:res=>{
let id=res.playlist.trackIds[0].id;
console.log(id)
$.ajax({
url:`${baseUrl}song/url?id=${id}`,
success:res=>{
console.log(res)
}
})
}
})
}
})
二、解决回调地狱
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
- 执行一个promise
- await一定要跟promise
- await一定要在async函数里面使用
- 跟在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()