前言
本文将介绍Promise的使用。
由于没有后端代码,对于ajax异步请求事件的实现就用setTimeout()
函数代替:
1 2 3
| setTimeout(() => { console.log('Hello World'); }, 1000)
|
Promise
ES6提供了Promise对象。对于有异步请求的需求时,可以使用Promise对异步操作进行封装。其优势就是可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数(“回调地狱”)。
基本使用
创建
可以直接使用new来调用Promise的构造器来进行实例化:
1 2 3
| new Promise((resolve, reject) => { })
|
说明:
Promise的参数为一个函数,该函数又会调用resolve
或者reject
函数
三种状态
Promise 对象有三种状态:
- pending: 初始状态,不是成功或失败状态
- fulfilled: 意味着操作成功完成
- rejected: 意味着操作失败
使用
当异步请求成功时,会调用resolve
函数,其中该函数的参数即为请求的数据,在Promise
对象的末尾可以接promise.then()
函数,其中请求的数据可以被then()
接收,进行处理:
1 2 3 4 5 6 7 8 9 10
| const data = 1
new Promise((resolve, reject) => { setTimeout(() => { resolve(data) },1000) }).then((data) => { data = data + 2 console.log('参数接收并修改为:' + data) })
|
当异步请求失败时,会调用reject
函数,该函数中的参数可以设置为一些错误信息,在Promise
对象的末尾可以接promise.catch()
函数,其中错误信息可以被catch()
接收:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const data = 1
new Promise((resolve, reject) => { setTimeout(() => {
reject('未请求到数据') },1000) }).then((data) => { data = data + 2 console.log('参数接收并修改为:' + data) }).catch((err) => { console.log(err) })
|
此外,promise.then()
函数可以同时接收两个参数,即resolve
传递的请求数据以及reject
传递的错误信息,因此可以使用以下格式简写:
new Promise((*resolve*, *reject*) *=>* {}).then(*data* *=>* {}, *err* *=>* {})
1 2 3 4 5 6 7 8 9 10 11 12 13
| const data = 1
new Promise((resolve, reject) => { setTimeout(() => { resolve(data) reject('未请求到数据') }, 1000) }).then(data => { data = data + 2 console.log('参数接收并修改为:' + data) }, err => { console.log(err) })
|
Promise的链式调用
链式调用
无论是promise.then()
函数还是promise.catch()
函数,都可以返回一个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 28 29 30 31 32 33
| const data = 1
new Promise((resolve, reject) => { setTimeout(() => { resolve(data) }, 1000) }).then((data2) => { data2 = data2 + 1 console.log('处理第一次请求数据,将其改为:' + data2)
return new Promise((resolve, reject) => { setTimeout(() => { resolve(data2) }, 1000) }) }).then((data3) => { data3 = data3 + 1 console.log('处理第二次请求数据,将其改为:' + data3)
return new Promise((resolve, reject) => { setTimeout(() => { resolve(data3) }, 1000) }) }).then((data4) => { data4 = data4 + 1 console.log('处理第三次请求数据,将其改为:' + data4) }).catch((err) => { console.log(err) })
|
运行结果如下:
说明:
可以在任意位置调用promise.catch()
函数进行错误捕获,一旦在这函数之前的“链”中有异步请求错误,都会捕捉到这一信息。
简写一
new Promise(resolve => resolve(结果))
可以简写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const data = 1
new Promise((resolve, reject) => { setTimeout(() => { resolve(data) }, 1000) }).then((data2) => { data2 = data2 + 1 console.log('处理第一次请求数据,将其改为:' + data2) return Promise.resolve(data2) }).then((data3) => { data3 = data3 + 1 console.log('处理第二次请求数据,将其改为:' + data3) return Promise.resolve(data3) }).then((data4) => { data4 = data4 + 1 console.log('处理第三次请求数据,将其改为:' + data4) }).catch((err) => { console.log(err) })
|
说明:
可以在新的请求后添加throw
关键词,以将错误信息抛出,最后可以用promise.catch()
函数进行捕获。
简写二
可以进一步把Promise.resolve()
省略:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const data = 1
new Promise((resolve, reject) => { setTimeout(() => { resolve(data) }, 1000) }).then((data2) => { data2 = data2 + 1 console.log('处理第一次请求数据,将其改为:' + data2) return data2 }).then((data3) => { data3 = data3 + 1 console.log('处理第二次请求数据,将其改为:' + data3) return data3 }).then((data4) => { data4 = data4 + 1 console.log('处理第三次请求数据,将其改为:' + data4) }).catch((err) => { console.log(err) })
|
说明:
return
默认返回的数据可以作为新的请求。
后记
为了更好的理解axios。