# promise 对象
Promise 是异步编程的一种解决方案,目的是为异步编程提供统一接口。
- 回顾之前的异步编程,通过事件回调函数来编写异步代码。可能会出现不断回调的问题——回调地狱。
- 通过promise编写异步代码
# 写法
# 实例化
使用Promise()构造函数 new Promise()
- Promise(function(){}) 参数为一个回调函数。
- 回调函数参数
- resolve
异步操作成功后需要调用的函数。
- reject
异步操作失败后需要调用的函数。
const p = new Promise(function (resolve, reject) {
//内部一般写需要异步操作的任务
//不写异步操作按照主线程上执行
fs.readFile('./01test.txt', 'utf8', (err, data) => {
!(err) ? resolve(data) : reject(err);
});
});
1
2
3
4
5
6
7
2
3
4
5
6
7
注意
当实例化Promise时回调函数立即执行。
# 使用Promise()的实例
1. 两个函数
Promise.prototype.then()
- 参数:为一个回调,具体是resolved的回调函数。
- 返回值:是一个新的Promise实例
- 支持链式编程
Promise.prototype.catch()
- 参数为一个回调,具体是reject的回调函数。
- 返回值:是一个新的Promise实例
注意
两个函数的回调都是异步执行。
2. 执行情况
- 当p的状态为fulfiled时执行then
- 当p的状态为rejected时执行catch
// 对p实例对象使用.then,当实例状态为fullfilled是执行其回调函数。
p.then((res) => {
console.log(res);
// 使用.catch,当异步任务抛出错误,实例对象状态为rejected时,被catch捕获,执行回调。
}).catch((err) => {
console.log(err);
});
1
2
3
4
5
6
7
2
3
4
5
6
7
# Promise 实例的三个状态
- pending 等待中, 默认状态
- fulfilled 成功
- rejected 失败
1. 状态变化
Promise 状态只能改变一次,改变一次后就会状态凝固,再次调用 resolve 或者 reject 将毫无意义,即:
- 如果异步任务执行成功,调用 resolve(),会将状态从 Promise ==> fulfilled;
- 如果异步任务执行失败,调用 reject(),会将状态从 Promise ==> rejected;
2. 执行情况:
- 当p的状态为fulfiled时执行 then
- 当p的状态为rejected时执行 catch
# 应用: 使用promise封装一个ajax请求
Promise.prototype.then()支持链式编程。
- promise 支持通过 .then 进行链式编码 (.then 然后) 前面的执行完了, 才会考虑 .then中的内容。
- 如果返回的是普通的值, 在后面一个.then中, 可以直接接收结果。
- 如果返回的是promise对象, 在后面一个.then中, 接收到的就是成功的结果。
//功能:模拟一个简单的axios
/*
原
axios({
method: "",
url: "",
})
*/
function axios(params) {
return new Promise((resolve, reject) => {
//ajax五步
const xhr = new XMLHttpRequest();
xhr.open(params.method, params.url);
xhr.send(null);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log("请求成功");
resolve(JSON.parse(xhr.responseText));
} else {
console.log('请求失败');
reject(new Error(xhr.responseText));
}
}
}
});
}
axios({
method: 'get',
url: 'http://localhost:3000/list'
}).then((res) => {
console.log(res);
return axios({
method: 'get',
url: 'http://localhost:3000/list/2'
});
}).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
});
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
32
33
34
35
36
37
38
39
40
41
42
43
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
32
33
34
35
36
37
38
39
40
41
42
43
虽然promise解决了回调地狱的问题,但是依然是不断.then
,语义化不好,为解决这个问题,引入async
与await