Promise
Promise作为面试中的经典考题,我们一定要深刻学习和理解它!
Promise有什么用呢?
答:我们拿它解决异步回调问题。
一、概念:
异步回调的一个很大的问题在于callback hell也就是“回调地狱”。多层嵌套回调函数,严重影响代码规范。Promise实际上是把回调函数从doSomething函数中提取到了后面的then()方法里,从而防止多重嵌套。一个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>promise</title>
</head>
<body>
<!-- 目标:拿到关于 狙击手 电影的描述
过程:
1.先登录
2.请求导演信息,找到张导的id
3.请求电影信息 找到描述 -->
</body>
<script src="js/jquery-3.6.0.min.js"></script>
<script>
// 1.登录
$.ajax({
type: 'get',
url: 'json/login.json',
success(res) {
// console.log(res);
// console.log(typeof res[0].code);
if (res[0].code / 1 === 200) {
// 2.请求导演信息,找到张导的id
$.ajax({
type: 'get',
url: 'json/director.json',
success(res) {
let id = 0;
res.some(d => {
if (d.name === '张导') {
id = d.id;
return true;
}
return false;
})
// 3.请求张导的电影数据,并拿到狙击手的信息
$.ajax({
type: 'get',
url: 'json/' + id + ".json",
success(res) {
console.log(res);
}
})
}
})
}
}
})
</script>
</html>
效果:
可看出,上述代码多层嵌套 ,接下来我们解决"回调地狱"的问题,使用Promise
二、使用方法:
Promise的构造函数用来构造一个Promise对象,其中入参匿名函数中resolve和reject这两个也都是函数。如果resolve执行了,则出发Promise.then中成功的回调函数,如果reject执行了,则触发了promise.then中拒绝的回调函数。
代码:
<!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>promise2</title>
</head>
<body>
</body>
<script>
let pro = new Promise((resolve,reject)=>{
if(Math.random()>0.5){
resolve("I'm resolve");
}else{
reject("I'm reject");
}
})
pro.then((res)=>{
console.log(res);
}).catch((err)=>{
console.log(err);
})
</script>
</html>
对上述实例代码的改进:
<!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>promise3</title>
</head>
<body>
<!-- 1.先登录
2.请求导演信息,找到张导的id
3.请求电影信息 找到描述 -->
</body>
<script src="js/jquery-3.6.0.min.js"></script>
<script>
// 1.登录
function myLogin() {
return new Promise((resolve, reject) => {
$.ajax({
type:'get',
url:'json/login.json',
success(res){
resolve(res);
},
error(err){
reject(err);
}
})
});
}
// 2.导演列表
function myDirector(){
return new Promise((resolve,reject)=>{
$.ajax({
type:'get',
url:'json/director.json',
success(res){
resolve(res);
},
error(err){
reject(err);
}
})
})
}
// 3.电影信息
function myFilm(id){
return new Promise((resolve,reject)=>{
$.ajax({
type:'get',
url:'json/'+id+'.json',
success(res){
resolve(res);
},
error(err){
reject(err);
}
})
})
}
myLogin()
.then(res=>{
return myDirector();
})
.then(res=>{
return myFilm(3);
})
.then(res=>{
console.log(res);
})
.catch(err=>{
console.log(err);
})
// let myLogin = () => new Promise();
</script>
</html>
解决了层层嵌套的问题。