0%

【Vue】Promise

多重异步操作的优雅写法,为axios框架铺垫基础

一、Promise的介绍和基本使用

1.1 什么是Promise

  • Promise是ES6中非常重要且非常好用的特性
  • Promise是异步编程的一种解决方案,对异步操作变得优雅
  • 异步操作一般用于网络请求

1.2 Promise基本使用

1
2
3
4
5
6
7
//简单的异步操作
setTimeout(() => {
console.log("Hello Vue!");
setTimeout(() => {
console.log("Hello Promise!")
}, 1000);
}, 1000);
  • 将上面的异步操作使用Promise进行封装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* 使用Promise封装异步操作
* new Promise(函数) --> 函数:(resolve, reject) => {异步操作}
* resolve 和 reject本身又是函数
* 使用方式为链式编程
*/
new Promise((resolve, reject) => {
//第一次网络请求
setTimeout(() => {
resolve();
}, 1000);
}).then(() => {
//第一次网络请求的处理结果
console.log("Hello Vue!");

return new Promise((resolve, reject) => {
//第二次网络请求
setTimeout(() => {
resolve()
}, 1000);
});
}).then(() => {
//第二次网络请求的处理结果
console.log("Hello Promise!");
});

1.3 resolve和reject使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// resolve 和 reject 的使用
// resolve:解析, reject:拒绝
//没有出错就进行解析,出现错误就拒绝
new Promise((resolve, reject) => {
if(true) {
resolve("成功调用哦!");
}else {
reject("调用失败!");
};
}).then((success) => { //resolve执行此方法
console.log(success);
}).catch((error) => { //reject执行此方法
console.log(error);
})

二、Promise基本使用补充

2.1 Promise三种状态

  • pending:等待状态,比如正在进行网络请求,或者定时器没有到时间
  • fulfill:满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调.then()
  • reject:拒绝状态,当我们主动回调了reject时,就处于该状态,并且会回调.catch()

2.2 resolve和reject的另一种写法

1
2
3
4
5
6
7
8
9
10
11
12
//resolve和reject的另一种写法
new Promise((resolve, reject) => {
if(true) {
resolve("成功调用哦!");
}else {
reject("调用失败!");
};
}).then(success => { //then可以直接传入两个函数,参数1为resolve调用,参数2为reject调用
console.log(success);
}, error => {
console.log(error);
});

三、Promise的链式调用

3.1 基本实现例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//需求:第一个异步操作后,再进行拼接字符
new Promise(resolve => {
setTimeout(() => {
resolve();
}, 1000);
}).then(() => {
const data = "Hello";
//假设还有其他异步代码

return new Promise(resolve => {
resolve(data);
});
}).then(data => {
data = data + " Promise!"; //拼接字符串
console.log(data);
});

3.2 使用Promise静态方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//但是拼接字符串的操作并没有进行异步使用,不太需要创建一个新的Promise对象
//Promise提供方法进行调用
new Promise(resolve => {
setTimeout(() => {
resolve();
}, 1000);
}).then(() => {
const data = "Hello";
//假设还有其他异步代码

return Promise.resolve(data); //直接调用静态方法resolve()
}).then(data => {
data = data + " Promise!"; //拼接字符串
console.log(data);
});

3.3 最终简化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Promise官方还支持更加简洁的写法
new Promise(resolve => {
setTimeout(() => {
resolve();
}, 1000);
}).then(() => {
const data = "Hello";
//假设还有其他异步代码

return data; //直接返回字符串
}).then(data => {
data = data + " Promise!"; //拼接字符串
console.log(data);
});

3.4 reject简化

  • reject的简化和resolve基本一样
1
2
3
4
5
//(1)
Promise.reject("使用静态方法")

//(2)等同于resolve的 return 字符串;
throw "手动抛出异常!"

四、all方法

需求:一个处理需要发送两个请求才能开始处理

4.1 普通方法实现

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
let resulet1 = false; //定义变量判断请求完成状态
let resulet2 = false;

$.ajax({
url: "url1",
success: function (data) {
console.log("结果一");
resulet1 = true;
handle(); //由于网络请求不确定谁快谁慢,所以两个请求都追加处理方法
}
});

$.ajax({
url: "url2",
success(data) {
console.log("结果二");
resulet2 = true;
handle();
}
})

function handle() {
if (resulet1 && resulet2){
console.log("结果已处理!")
}
}

4.2 使用Promise实现

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
//用promise的all方法解决两个请求同时处理的问题
//all方法传递一个数组,数组内容为异步操作
Promise.all([
new Promise(resolve => {
$.ajax({
url: "url1",
success(data){
console.log("结果一");
resolve(data)
}
})
}),
new Promise(resolve => {
$.ajax({
url: "url1",
success(data){
console.log("结果2");
resolve(data)
}
})
})
]).then(result => {
console.log(result);
console.log("结果已处理")
})
</script>