本文已参与「新人创作礼」活动,一起开启掘金创作之路。
1.什么是Promise?
- Promise是异步编程的一种解决方案。
- 异步事件:我们封装一个网络请求的函数,因为不能立即拿到结果,所以往往我们会传入另外一个函数,在数据请求成功时,将数据通过传入的函数回调出去
2.之前的解决方法ajax
-
问题:回调地狱
-
我们需要通过一个url1从服务器加载一个数据data1,data1中包含了下一个请求的url2我们需要通过data1取出url2,从服务器加载数据data2,data2中包含了下一个请求的url3我们需要通过data2取出url3,从服务器加载数据data3,data3中包含了下一个请求的url4发送网络请求url4,获取最终的数据data4
-
是不是感觉太不直观了,Promise就是解决这个的。
3.Promise的基本使用
注: 一般情况下,又异步操作的时候,使用Promise对这个异步操作进行封装。 new Promise --> 构造函数(1保存一些状态信息 2.执行传入的函数) 在执行我们传入的回调函数时,会传入两个参数,resolve,reject 本身又是函数
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>Document</title>
</head>
<body>
<div id='app'>
</div>
<script src='../js/vue.js'></script>
<script>
new Promise((resolve,reject)=>{
setTimeout(()=>{
//成功的时候,调用resolve
//resolve("hello world")
//失败的时候,调用reject
reject("error message")
},1000)
}).then((data)=>{
//1.100行代码,比较优雅
console.log(data);
}).catch((err)=>{
console.log(err);
})
</script>
</body>
</html>
- resolve,reject 本身他们又是函数
- resolve代表请求成功,然后会执行then函数;reject代表请求失败,然后会执行catch函数
4.Promise的链式使用
实现要求:
- 网络请求:aaa =>自己处理(10行)
- 处理:aaa+111 =>自己处理(10行)
- 处理:aaa+111+2222 =>自己处理(10行)
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>Document</title>
</head>
<body>
<div id='app'>
</div>
<script src='../js/vue.js'></script>
<script>
//网络请求:aaa =>自己处理(10行)
//处理:aaa+111 =>自己处理(10行)
//处理:aaa+111+2222 =>自己处理(10行)
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("aaa");
},1000)
}).then((res)=>{
//1.自己处理10行代码
console.log(res,'第一层10行代码');
//2.
return new Promise((resolve)=>{
resolve(res + '111')
})
}).then((res)=>{
console.log(res,'第二层10行代码');
//3.
return new Promise((resolve)=>{
resolve(res + '222')
})
}).then((res)=>{
console.log(res,'第三层10行代码');
})
</script>
</body>
</html>
- 注:链式调用,可以一层层的调用
- 乍看,其实感觉这比ajax的回调地狱更麻烦,但是有个好处是:我们可以给很好的区分出每次的请求和处理代码。
- 可以简写为:
///2.链式简写
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("aaa");
},1000)
}).then((res)=>{
//1.自己处理10行代码
console.log(res,'第一层10行代码');
//2.
return Promise.resolve(res + '111')
}).then((res)=>{
console.log(res,'第二层10行代码');
//3.
return Promise.resolve(res + '222')
}).then((res)=>{
console.log(res,'第三层10行代码');
})
- 进一步简写:
///3.链式再次简写
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("aaa");
},1000)
}).then((res)=>{
//1.自己处理10行代码
console.log(res,'第一层10行代码');
//2.
return res + '111';
}).then((res)=>{
console.log(res,'第二层10行代码');
return res + '222';
}).then((res)=>{
console.log(res,'第三层10行代码');
})
5.Promise的all函数使用
- 需求:两个异步处理的结果都返回时,执行下一步操作
- 1.ajax的实现
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>Document</title>
</head>
<body>
<div id='app'>
</div>
<script src='../js/vue.js'></script>
<script>
//请求一:
isResult1 = false;
isResult2 = false;
$ajax({
url:"",
success:function(){
console.log('结果1');
isResult1 = true;
handleResult()
}
})
//请求二:
$ajax({
url:"",
success:function(){
console.log('结果2');
isResult2 = true;
handleResult()
}
})
function handleResult(){
if(isResult1 && isResult2){
//
}
}
</script>
</body>
</html>
- 2.promise的all方法实现
- 当两个异步处理的结果都返回时,才会执行下一步then操作
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>Document</title>
</head>
<body>
<div id='app'>
</div>
<script src='../js/vue.js'></script>
<script>
//利用promise处理
Promise.all([
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("result1")
},2000)
}),
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("result2")
},1000)
}),
]).then(results =>{
console.log(results);
})
</script>
</body>
</html>