Promise
对象是一个代理对象(代理一个值),被代理的值在Promise
对象创建时可能是未知的。它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise
对象。
Promise的含义
Promise是ES6新增的异步编程解决方案,它是一个对象,可以通过Promise构造函数来实例化 new Promise(cb)
Promise内部的三种状态的(pending(进行中)、fulfilled(已成功)、rejected(已失败)),Promise 对象根据状态来确定执行哪个方法。Promise 在实例化的时候状态是默认 pending 的,当异步操作是完成的(调用resolve),状态会被修改为 fulfilled,如果异步操作遇到异常(调用reject),状态会被修改为 rejected,状态转化是单向的,不可逆转,已经确定的状态(fulfilled/rejected)无法转回初始状态(pending),而且只能是从 pending 到 fulfilled 或者 rejected
基本用法
1 | // 第一步 创建实例 |
常用方法
Promise.prototype.then()
它的作用是为promise实例添加状态改变时的回调函数1
2
3
4
5
6
7
8
9
10
11// then方法返回的是新的promise实例,因此可以采用链式操作
let promise = new Promise(resolve => {
resolve('ss')
})
promise.then(res => {
console.log(res) // ss
return Promise.resolve(res + 'hh')
}).then(res => {
console.log(res) // sshh
})
// 依次指定两个then回调函数,第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数Promise.prototype.catch()
使用 Promise 对象的 catch 方法来捕获异步操作过程中出现的任何异常。1
2
3
4
5
6
7
8
9function test () {
return new Promise((resolve, reject) => {
reject(new Error('es'))
})
}
test().catch((e) => {
console.log(e.message) // es
})
// 一般来说,不要在then方法中定义rejected状态的回调函数(即第二个参数),要使用catch来处理错误Promise.prototype.finally()
无论Promise对象的最后状态是啥,都会执行的操作1
2
3
4
5
6/* finally方法指定promise结束时,无论结果是fulfilled还是rejected,都会执行的回调函数,可以避免同样的处理语句在then和catch中都要写一次的情况 */
this.$request.then(() => {})
.catch(() => {})
.finally(() => {
this.loading = false
})Promise.resolve()
1
2
3
4// Promise.resolve()是Promise静态方法 Promise.resolve(value)可以认为是以下代码的语法糖。
new Promise(function (resolve) { resolve(42) })
// 方法 Promise.resolve(value) 的返回值也是一个 Promise 对象,所以我们可以像下面那样接着对其返回值进行 .then 调用。
Promise.resolve(42).then(function (value) { console.log(value) })Promise.reject()
1
2
3
4// Promise.reject()是Promise静态方法 Promise.reject(error)可以认为是以下代码的语法糖。
new Promise(function (resolve, reject) { reject(new Error('出错了')) })
// 这段代码的功能是调用该Promise 对象通过then指定的 onRejected 函数,并将错误(Error)对象传递给这个 onRejected 函数。
Promise.reject(new Error('BOOM!'))Promise.all(promiseArray)
用于将多个promise实例包装成一个新的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
27
28var p1 = Promise.resolve(1)
var p2 = Promise.resolve(2)
var p3 = Promise.resolve(3)
var p = Promise.all([p1, p2, p3]).then(function (results) {
console.log(results) // [1, 2, 3]
})
// Promise.all 接收由promise实例组成的数组作为参数,如果不是promise实例,会调用Promise.resolve()处理成promise实例再进行处理
// p的状态由 p1, p2, p3决定,分为两种情况
// 1. 只有p1、p2、p3的状态都变为fufilled成功,最终p的状态才会变成fulfilled成功,由p1、p2、p3返回值组成的数组传递给p的回调函数
// 如果参数中的任何一个promise为reject的话,则整个Promise.all调用会立即终止,并返回一个reject的新的 Promise 对象。
// 2. 只要p1、p2、p3之中有一个返回rejected失败,p的状态就变成了rejectd失败,此时返回的是第一个被reject的实例的返回值,传递给p的回调函数
// Promise.all并不是串行的 而是并行的 例如 数组中的每个请求都有延迟则promise.all()返回是延迟时间最长的大约是3s 而不是 6s
console.time()
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, 'pro1')
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 2000, 'pro2')
})
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'pro3')
})
Promise.all([promise1, promise2, promise3]).then((values) => {
console.timeEnd()
console.log(values)
})
// 3001.1630859375ms
// ["pro1", "pro2", "pro3"]Promise.race(promiseArray)
用于将多个promise实例包装成一个新的promise实例1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23var p1 = Promise.resolve(1)
var p2 = Promise.resolve(2)
var p3 = Promise.resolve(3)
Promise.race([p1, p2, p3]).then(function (value) {
console.log(value) // 1
})
// Promise.race返回一个新的 Promise对象。参数 promise 数组中的任何一个 Promise 对象如果变为 resolve或者 reject 的话,该函数就会返回,并使用这个 Promis 对象的值进行 resolve 或者 reject。返回最早完成的promise对象
console.time()
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, 'pro1')
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 2000, 'pro2')
})
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'pro3')
})
Promise.race([promise1, promise2, promise3]).then((values) => {
console.timeEnd()
console.log(values)
})
// 1000.848876953125ms
// pro3promise的链式调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21const promise1 = new Promise((resolve, reject) => {
resolve('pro1')
})
const promise2 = new Promise((resolve, reject) => {
resolve('pro2')
})
const promise3 = new Promise((resolve, reject) => {
resolve('pro3')
})
promise1.then((res1) => {
console.log(res1, 'res1')
return promise2
}).then((res2) => {
console.log(res2, 'res2')
return promise3
}).then((res3) => {
console.log(res3, 'res3')
})
// pro1 res1
// pro2 res2
// pro3 res3