32.Promise
leezozz 4/16/2023 js
# 1.Promise说明
Promise对象用于表示一个异步操作的最终完成(或失败)及其结果【抽象表达:Promise 是JS中进行异步编程的新的解决方案(旧的是谁?=> 纯回调的形式)】
异步方法并不会立即返回最终的值,而是会返回一个 promise,以便在未来某个时候把值交给使用者。
一个Promise必然处于以下几种状态之一:
- 待定(pending):初始状态,既没有被兑现,也没有被拒绝。(什么也不调用,或者返回一些值,promise对象就是等待状态)
- 已兑现(fulfilled):意味着操作成功完成。 (调用resolve,promise对象就是成功状态)
- 已拒绝(rejected):意味着操作失败。(调用reject,promise对象就是失败状态。抛异常throw,也是失败状态)
因为Promise.prototype.then和Promise.prototype.catch方法返回的是promise,所以它们可以被链式调用。
# 状态改变
- pending -> fulfilled
- pending -> rejected 且一个Promise对象只能改变一次,无论变成成功还是失败,都会有一个结果数据,成功的结果数据一般称为value,失败的结果数据一般称为reason。
// new Promise(构造函数),构造函数有两个参数:resolve, reject
const fetchData = new Promise((resolve, reject) => {
// 使用 Ajax 请求数据
ajax('http://example.com/data', (response) => {
if (response.status === 'success') {
resolve(response.data);
} else {
reject(new Error('Failed to fetch data'));
}
});
});
// 处理数据
fetchData.then((data) => {
// 成功获取数据
console.log(data);
}).catch((error) => {
// 获取数据失败
console.error(error);
});
// Promise.resolve(value):返回一个已经 resolved(成功)的 Promise 对象
return Promise.resolve('操作成功')
// Promise.reject(reason):返回一个已经 rejected(失败)的 Promise 对象
return Promise.reject(new Error('操作失败'));
// 调用函数a,console并不会执行。因为await的promise对象并没有执行调用resolve,此时promise处于pending状态,不会向下执行
const a = async() => {
const res = await new Promise((resolve) => {})
console.log('res', res)
}
a()
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
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
# 2.Promise.all()
Promise.all()等待所有都完成(或者第一个失败)
返回值:
- 如果传入的参数是一个空的可迭代对象,则返回一个已完成状态的Promise
- 如果传入的参数不包含任何promise,则返回一个异步完成Promise
- 其他情况下返回一个处理中(pending)的Promise。这个返回的promise之后会在所有的promise都完成或有一个promise失败时异步地变为完成或失败
var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
var p4 = Promise.reject(4)
const test = Promise.all([p1, p2, p3, p4]).then(values => {
console.log('values', values); // 此处不打印
});
// Promise {<rejected>: 4}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 3.Promise.race()
包含n个promise的数组,返回一个新的promise, 第一个完成的promise的结果状态就是最终的结果状态
// 产生一个成功值为 1 的 Promise 对象
const p1 = new Promise((resolve, reject) => {
resolve(1)
})
// 产生一个成功值为 2 的 Promise 对象
const p2 = Promise.resolve(2)
// 产生一个失败值为 3 的 Promise 对象
const p3 = Promise.reject(3)
// p1.then(value => console.log(value))
// p2.then(value => console.log(value))
// p3.catch(reason => console.error(reason))
const pAll = Promise.all([p1, p2, p3])
pAll.then(values => {
console.log('all onResolved()', values)
}, reason => {
console.log('all onRejected()', reason) // all onRejected() 3
})
const race = Promise.race([p1, p2, p3])
race.then(value => {
console.log('all onResolved()', value) // all onResolved() 1
}, reason => {
console.log('all onRejected()', reason)
})
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
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
# 4.promise.then()
promise.then()返回的新promise的结果状态由then()指定的回调函数执行的结果决定
- 如果抛出异常, 新promise变为rejected, reason为抛出的异常
- 如果返回的是非promise的任意值, 新promise变为resolved, value为返回的值
- 如果返回的是另一个新promise, 此promise的结果就会成为新promise的结果
new Promise((resolve, reject) => {
resolve(1)
}).then(
value => {
console.log('onResolved1()', value);
// return 1.1 或
return Promise.resolve(1.1)
// return Promise.reject(1.1)
// throw 1.1
},
reason => {
console.log('onRejected1()', reason);
}
).then(
value => { console.log('onResolved2()', value); },
reason => { console.log('onRejected2()', reason) }
)
// onResolved1() 1
// onResolved2() 1.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 5.回调地狱
回调地狱:回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回掉执行条件,代码是水平向右扩展
doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log('Got the final result: ' + finalResult)
}, failureCallback)
}, failureCallback)
}
// 回调地狱的缺点:不便阅读,不便于异常处理
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
解决方案:Promise 链式调用,代码水平向下扩展
doSomething().then(function(result) {
return doSomethingElse(result)
})
.then(function(newResult) {
return doThirdThing(newResult)
})
.then(function(finalResult) {
console.log('Got the final result: ' + finalResult)
})
.catch(failureCallback)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
终极解决方案:async/await,用同步的写法处理异步的操作
async function request() {
try {
const result = await doSomething()
const newResult = await doSomethingElse(result)
const finalResult = await doThirdThing(newResult)
console.log('Got the final result: ' + finalResult)
} catch (error) {
failureCallback(error)
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10