Promise 讲解

背景说明

从同步与异步说起:
JavaScript 中具有同步和异步的概念,最常⻅的异步操作莫过 Ajax,Ajax 是前后端数据交互的桥
梁。
异步操作特点:
同步任务总是顺序执⾏的。与同步任务不同,异步任务执⾏结果与书写顺序⽆关,例如,定时器结束时
间取决于延迟时间;Ajax 的响应成功时间取决于数据量与⽹速。
这就导致,如果要对异步操作的结果进⾏处理,就必须使⽤回调函数(
callback)。
问题出现:
思考:如果有多个请求,每个请求都依赖与前⼀个请求的结果,这时会发⽣什么呢?

这种层层嵌套的回调写法称为“回调地狱”

Promise 的作⽤:
Promise 是 ES2015(
ES6)中标准化的功能,⽤于 给异步编程提供⼀种书写更合理,功能更强的统
⼀的解决⽅案。
Promise 含义为承诺,是⼀个 ES6 提供的类型,使⽤时需要创建⼀个实例对象,指代我们要进⾏的⼀个操作(异步) 创建完毕, 这时 promise 处于⼀个“待定状态”, 最终结果可能为“成功状态”或“失败状态”。
举例增强理解:明天发⼯资,我要给我媳妇买个苹果,如果发⼯资了,就买⼀⽄,如果没发就算了,因为没有私房钱。
特点:结果明确后⽆法更改:例如,发⼯资后买了⼀⽄苹果,买了就是买了,不可能过⼀会⼉⼜变成了没买,这不合逻辑。
回归操作:那么对应操作中,利于⼀个 Ajax 请求,当请求成功或失败时,可以通过相应的“状态”进⾏ 执⾏结果的判断,从⽽进⾏相应的处理。
⼩结:Promise 对象的操作就是通过状态进⾏控制,状态变化会⾃动触发对应的回调。

Promise 使⽤

创建实例⽤于存储异步操作
参数为函数,在创建实例时同步执⾏
函数有两个参数,都是函数,调⽤时可决定 promise 对象的状态
resolve(data) 传递成功时的结果
reject(err) 传递失败时的错误信息
注意,由于promise 对象的结果明确后⽆法更改,所以两个函数在逻辑中只能有⼀个被执⾏。
const promise = new Promise( function () {

 resolve(100)

// reject(new Error('error message!'))
})
当 promise 对象的状态确定时,会触发对应的回调函数进⾏处理,我们需要通过 promise 对象的⽅法指定这些回调函数:
then() 成功时的处理函数
catch() 失败时的处理函数
1 const promise = new Promise( function ( resolve , reject ) {
2 resolve ( 100 )
3 // reject(new Error('error message!'))
4 })
5 // 也可以通过 new Promise().then().catch() ⽅式进⾏链式调⽤。
6 promise. then ( function ( value ) {
7 console. log ( ' 成功了,数据为: ' , value )
8 }). catch ( function ( error ) {
9 console. log ( ' 失败了,错误为: ' , error )
10 })
Promise 练习:封装 Ajax 函数
1 function ajax ( url ) {
2 return new Promise( function ( resolve , reject ) {
3 const xhr = new XMLHttpRequest()
4 xhr . open ( 'GET' , url )
5 xhr . responseType = 'json'
6 xhr . onload = function () {
7 if ( this . status === 200 ) {
8 // 接收到响应数据,标记状态为成功,并传递给 then 中的回调处理
9 resolve ( this . response )
10 } else {
11 // 失败时更改状态,并传递错误信息
12 reject ( new Error( this . statusText ))
13 }
14 }
15 // 发送请求
16 xhr . send ()
17 })
18 }
19 const successUrl = 'http://edufront.lagou.com/front/course/getPur
chaseCourse'
20 const failUrl = 'http://eduboss.lagou.com/boss/course/changeStat
e'
21
22 ajax(failUrl). then ( function ( res ) {
23 console. log ( res )
24 }). catch ( function ( error ) {
25 console. log ( error )
26 })
如果仅仅是这样使⽤,请求多了,依然会出现嵌套的问题,这时要注意使⽤⽅式,不要嵌套书写,⽽是利
⽤ Promise 的链式调⽤进⾏操作。
1 // 错误写法
2 ajax(successUrl)
3 . then ( function ( res ) {
4 console. log ( res )
5 ajax(successUrl)
6 . then ( function ( res ) {
7 console. log ( res )
8 ajax(successUrl)
9 . then ( function ( res ) {
10 console. log ( res )
11 })
12 })
13 })
链式调⽤
then() 调⽤的返回值为⼀个新的 Promise 对象,如果要在⼀次异步操作后再执⾏下⼀个异步操作,应当通过这个新的 Promise 对象进⾏处理,这样就可以避免回调地狱啦。
1 // 执⾏示例
2 ajax(successUrl)
3 . then ( function ( res ) {
4 console. log ( 1 )
5 })
6 . then ( function ( res ) {
7 console. log ( 2 )
8 })
9 . then ( function ( res ) {
10 console. log ( 3 )
11 })
在 then() 中通过 return 返回 promise 对象会被设置为 then() 的返回值。
1 // 顺序执⾏异步操作实例
2 ajax(successUrl)
3 . then ( function ( res ) {
4 console. log ( 1 , res )
5 return ajax(successUrl)
6 })
7 . then ( function ( res ) {
8 console. log ( 2 , res )
9 return ajax(successUrl)
10 })
11 . then ( function ( res ) {
12 console. log ( 3 , res )
13 return ajax(successUrl)
14 })
如果返回的是普通值,则会包裹在默认的 promise 对象中,传递给 then ⽅法,不传时默认为 undefined
1 ajax(successUrl)
2 . then ( function ( res ) {
3 console. log ( 1 , res )
4 return ajax(successUrl)
5 })
6 . then ( function ( res ) {
7 console. log ( 2 , res )
8 // return ajax(successUrl)
9 return [ 1 , 2 , 3 ]
10 })
11 . then ( function ( res ) {
12 console. log ( 3 , res ) // 3, [1, 2, 3]
13 return ajax(successUrl)
14 })
总结:promise 本质上就是通过回调函数定义异步任务结束后所需要执⾏的任务,只不过回调是通过
then() 进⾏设置,由于 then() 可以进⾏链式调⽤,所以避免了层层嵌套的书写⽅式。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值