promise
认识promise
首先介绍下promise,是es6规范中,新增的一个源生方法,常用于异步编程,取代之前回调套回调的方法。
如何理解promise是一个比较难的点,通俗一点的解释就是,promise就相当于我给你一个承诺(就像字面意思一样),你不需要管他是否执行完成。
用ajax来说,promise在ajax发起的时候就返回给调用者,暂时先不要关心内容是什么,你只需要知道在他有最终结果的时候,他会执行你的指令。
promise有三个状态,分别是pending
进行中、resolved
已完成、rejected
已失败,首先他返回的,是进行中。等运行完成后,会根据你的逻辑进行返回。
示例:封装ajax
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
function (uri,method,req){
return
new
Promise(
function(resolve,reject){
if(
200 ){
resolve(
true);
}
if(
500 ){
reject(
500)
}
})
}
fetch(
'/api/info',
'get',
null)
.then(
function (data){
console.log(data);
})
.catch(
function (error) {
console.log(error);
});
|
例如上面就是一个简单的ajax的封装,这个promise可以让你调用promise的两个方法,实现ajax后的操作
async
async与await
async
是一个异步函数的标志,是es7中新增的一项规范,注意,async是一个关键字
通常与async
搭配使用的是await
标志,async
代表他是一个异步函数,而await
则是表示要等到这个异步函数执行完成后,在进行下面的操作。注意,await
只能在async
函数中使用
下面我们先使用这两个关键字实现一个方法。后续代码我会使用es6语法进行编写
1
2
3
4
5
6
|
const method1 =
data => {
return data
};
const method2 =
async data => {
return
await data;
};
|
以上两种方法可以说是一样的,甚至对于method2
来说有点多余。但是到了真正的异步函数中,async
与await
就大显身手了
回调的痛点
在用新语法解决问题之前,我们来看一下之前开发的一些痛点,回调函数,有人把它叫做飞机函数,就像下面
1
2
3
4
5
6
7
|
fn1(
'a',data1=>{
fn2(
'b',data2=>{
fn3(
'c',data3=>{
})
})
})
|
展示了一架小飞机。业务逻辑中,越来越多的ajax或者其他异步操作,让我们不得不在回调中判断上一步的操作,然后再进行下一步,这种回调嵌套回调的方法,在维护起来,是个很头疼的事情。所以我们来解决它。
promise与async的结合
上文中的ajax封装最终采用的就是回调,还记得那个.then
方法吗,我们重写它
1
2
3
4
5
7
8
9
10
11
12
13
14
15
16
17
18
|
const method1 =
data => {
return
new
Promise(
(resolve,reject)=>{
if(
200 ){
resolve(
true);
}
if(
500 ){
reject(
false)
}
})
};
const method2 =
async data => {
retur data;
};
const result =
await method1(
1);
|
回调消失了,我们使用await等来了最终结果,让一个异步方法顺序执行了
promise.all的扩展
代码痛点
很多时候,我们发送多个接口,并判断他们是否都成功了,只有在都成功的情况下再进行操作。
我们首先想到的办法是,计数器。
1
2
3
4
5
6
7
8
9
10
|
const arr = [
1,
2,
3];
let ajaxTimes = arr.length;
arr.map(
i => {
ajaxTimes --;
if(!ajaxTimes){
}
})
|
- 并不是同时发送请求,而是依次发送
- 如果有一个方法失败,定位失败较难
- 依旧是我们熟悉的回调
- 每次都要判断次数是否到达
解决办法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
const arr = [
1,
2,
3];
let promiseArr = [];
const proFactory =
data =>{
return
new
Promise(
(resolve,reject)=>{
if(
200 ){
resolve(
true);
}
if(
500 ){
reject(
false)
}
})
};
const proAll =
list => {
return
new
Promise(
(resolve,reject)=>{
Promise.all(list)
.then(
data=>{
resolve(data)
})
.catch(
error=>{
reject(error)
})
})
};
arr.map(
i => {
promiseArr.push(proFactory(i))
});
const res =
await proAll(proAll(promiseArr));
|