Promise实例方法

本文最后更新于:8 个月前

Promise的3种实例方法介绍、手写实现

Promise实例方法

Promise实例方法定义在Promise原型上
image-20230513114023572

一、then()

then()是为Promise实例添加处理程序的主要方法
1
2
3
4
5
6
7
8
9
10
var p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('success')
},1000)
})

p.then((result)=>{console.log('1',result)})
p.then((res)=>{console.log('2',res)})
// 1 success
// 2 success

1.参数

  • 参数一:onResolved函数,可选
  • 参数二:onRejected函数,可选

注意:如果传入的参数为非function类型,会被忽略。

1
2
3
4
5
6
7
let p = new Promise((resolve,reject)=>{...})
function onResolved(){...}
function onRejected(){...}

p.then(onResolved)
p.then(null, onRejected)
p.then(onResolved, onRejected)

2.返回值

then方法返回一个新的Promise实例。这个新的Promise实例是会自动被Promise.resolve方法包装。

返回值的状态需要根据不同情况进行区分

  • (1)父级状态为pending
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var p = new Promise(()=>{})
var p1 = p.then(()=>'bar')
var p2 = p.then(()=>{throw 'err'})
var p3 = p.then(()=>Promise.resolve('bar'))
var p4 = p.then(()=>Promise.reject('foo'))
p1 // Promise {<pending>}
p2 // Promise {<pending>}
p3 // Promise {<pending>}
p4 // Promise {<pending>}

var p = new Promise(()=>'bar')
var p1 = p.then(()=>{})
p1 // Promise {<pending>}
// 以上所有实例的PromiseState都是pending
// 所有PromiseResult都是undefined,因为只有resolve或者reject方法才能向then中传递参数值

父级Promise实例状态为pending时,then()返回的所有实例都是对父级Promise实例的继承


  • (2)父级状态为resolved
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var p = Promise.resolve('init')
var p0 = p.then(()=>{})
var p1 = p.then(()=>'bar')
var p2 = p.then(()=>{throw 'err'})
var p3 = p.then(()=>Promise.reject())
var p4 = p.then(()=>new Promise(()=>{}))
var p5 = p.then()
p // Promise {<fulfilled>: 'init'}
p0 // Promise {<fulfilled>: undefined}
p1 // Promise {<fulfilled>: 'bar'}
p2 // Promise {<rejected>: 'err'}
p3 // Promise {<rejected>: undefined}
p4 // Promise {<pending>}
p5 // Promise {<fulfilled>: 'init'}

then()返回的实例是 Promise.resolve()方法 对onResolved处理程序的返回值 的包装

如果没有提供onResolved处理程序,返回的是Promise.resolve()对父级Promise实例的包装


  • (3)父状态为rejected
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var p = Promise.reject('init')
var p1 = p.then()
var p2 = p.then(null, ()=>{})
var p3 = p.then(null, ()=>'bar')
var p4 = p.then(null, ()=>{throw 'err'})
var p5 = p.then(null, ()=>{return new Promise(()=>{})})
var p6 = p.then(null, ()=>Promise.resolve('bar'))
var p7 = p.then(null, ()=>Promise.reject('bar'))
p1 // Promise {<rejected>: 'init'}
p2 // Promise {<fulfilled>: undefined}
p3 // Promise {<fulfilled>: 'bar'}
p4 // Promise {<rejected>: 'err'}
p5 // Promise {<pending>}
p6 // Promise {<fulfilled>: 'bar'}
p7 // Promise {<rejected>: 'bar'}

then()返回的实例是Promise.resolve()方法对onRejected处理程序返回值 的包装

如果没有提供onRejected处理程序,则返回Promise.resolve()对父级Promise实例的包装



二、catch()

catch()用于为 Promise实例 添加 onRejected 处理程序,它是一个语法糖,catch(onRejected) 相当于 then(null, onRejected)

1.参数

只接受一个参数,onRejected处理函数

1
2
var p = Promise.reject('err')
var p1 = p.catch((err)=>{console.log(err)})
1
2
3
var p = new Promise((resolve,reject)=>{...})
p.then(()=>{...})
.catch(()=>{...})

2.返回值

Promise实例,与 then() 的 onRejected 处理程序一致(即父级Promise实例状态为rejected时)

1
2
3
4
5
var p = Promise.reject('err')
var p1 = p.catch((err)=>{console.log(err)})
var p2 = p.catch()
p1 // Promise {<fulfilled>: undefined}
p2 // Promise {<rejected>: 'err'}
1
2
3
4
5
6
// 尝试:resolved的实例调用catch()会发生什么?
var p = Promise.resolve('init')
var p1 = p.catch()
var p2 = p.catch((err)=>{console.log(err)})
p1 // Promise {<fulfilled>: 'init'}
p2 // Promise {<fulfilled>: 'init'}
  • 如果没有传入onRejected处理函数,返回Promise.resolve()对父级Promise实例的包装
  • 否则,返回Promise.resolve()onRejected处理函数的返回值的包装



三、finally()

finally() 用于给Promise实例添加 onFinally 处理程序,这个处理程序会在状态发生转换(pending -> resolved 或 pending -> rejected)时执行,它存在的意义在于避免 onResolved 和 onRejected 处理程序中出现重复冗余的代码

1.参数

接受一个函数作为参数

1
2
3
4
var p = new Promise((resolve, reject)=>{...})
p.then(()=>{...})
.catch(()=>{...})
.finally(()=>{...})

2.返回值

新的Promise实例,大多数情况下表现为对父级Promise实例的传递,对于解决和拒绝状态都是,不会被改变。(onFinally处理程序抛出异常时除外)

1
2
3
4
5
6
7
let p1 = Promise.resolve('foo');
let p2 = Promise.reject('bar');
let p3 = p1.finally(()=>'qux'); //Promise {<fulfilled>: 'foo'}
let p5 = p2.finally(()=>'qux'); //Promise {<rejected>: 'bar'}

let p4 = p2.finally(()=>{throw 'err'}); //Promise {<rejected>: 'err'}
// onFinally处理程序抛出异常时,返回一个拒绝的Promise实例,PromiseResult为抛出的值

Promise实例方法
http://timegogo.top/2023/05/13/JavaScript/JavaScript异步(二)Promise实例方法/
作者
丘智聪
发布于
2023年5月13日
更新于
2023年7月16日
许可协议