Promise之关键问题
1、如何改变 promise 的状态
resolve(value): 如果当前是pending就会变成 resolved
reject(reason): 如果当前是pending就会变成 rejected
抛出异常:如果当前是pending就会变为rejectd
🌰示例
<script> let p = new Promise((reosolve, reject) => { //1. resolve 函数 reosolve('ok'); // pending => fulfilled (resolved) //2. reject 函数 reject('error'); // pending => rejected //3. 抛出错误 throw '出问题了'; // pending => rejected }) console.log(p); </script>
2、一个promise指定多个成功/失败回调函数,都会调用吗?
当前promise对象改变为对应状态时都会调用
🌰示例:pending => fulfilled (resolved)
⏰ pending => fulfilled (resolved)
<script> let p = new Promise((reosolve, reject) => { //1. resolve 函数 reosolve('ok'); // pending => fulfilled (resolved) }) p.then((value) => { console.log(value); }) p.then((value) => { console.log(value) }) p.then((value) => { console.log(value); }) </script>
结果:
⏰ pending => rejected
<script> let p = new Promise((reosolve, reject) => { //1. reject 函数 reject('ok'); // pending => rejected }) p.catch((value) => { console.log(value); }) p.catch((value) => { console.log(value) }) p.catch((value) => { console.log(value); }) </script>
结果

3、promise.then() 返回的新promise的结果由什么决定?
⏰ 简单表达式: 由then()指定的回调函数执行的结果决定
//1. 创建一个promise let p = new Promise((reosolve, reject) => { reosolve('ok') }) //2.执行then方法 let result = p.then((ref) => { console.log(ref) }, (reason) => { console.log(reason); })
先解决一个问题,p 和 result 是不是同一个promise? 我们验证一下
if (p === result) { console.log('执行then方法返回的还是旧promise') } else { console.log('执行then方法产生了新的promise'); }
结果

我们可以得出结论promise.then() 返回了新promise。那么新promise 状态和值由谁确定呢?
- 正常态
<script> //1. 创建一个promise let p = new Promise((reosolve, reject) => { reosolve('ok') }) console.log('p:', p) //2.执行then方法 let result = p.then((ref) => { console.log(ref) }, (reason) => { console.log(reason); }) console.log('result:', result) </script>
结果
![]()
- 失败态
<script> //1. 创建一个promise let p = new Promise((reosolve, reject) => { reject('error') }) console.log('p:', p) //2.执行then方法 let result = p.then((ref) => { console.log(ref) }, (reason) => { console.log(reason); }) console.log('result:', result) </script>
结果
![]()
- 抛出异常
<script> //1. 创建一个promise let p = new Promise((reosolve, reject) => { throw '异常了' }) console.log('p:', p) //2.执行then方法 let result = p.then((ref) => { console.log(ref) }, (reason) => { console.log(reason); }) console.log('result:', result) </script>
结果
![]()
❗️ 由此,我们可以得出结论,p 与 result 的状态和 存储值 之间没有任何关系。而是取决于then()指定的回调函数执行的结果。详细情况,看下面
⏰ 详细表达式:
-
如果抛出异常,新promise 变为rejected, reason 为抛出的异常
<script> //1. 创建一个promise let p = new Promise((reosolve, reject) => { reosolve('ok') }) console.log('p:', p) //2.执行then方法 let result = p.then((ref) => { console.log(ref) //1.抛出错误 throw '抛出异常' }, (reason) => { console.log(reason); }) console.log('result:', result) </script>
结果
![]()
-
如果返回的是非promise的任意值, 新promise 变为 resolved, value为返回的值
<script> //1. 创建一个promise let p = new Promise((reosolve, reject) => { reosolve('ok') }) console.log('p:', p) //2.执行then方法 let result = p.then((ref) => { console.log(ref) //1.抛出错误 // throw '抛出异常' //2.返回结果是 非promise 类型的对象 return 521 }, (reason) => { console.log(reason); }) console.log('result:', result) </script>
结果
![]()
-
如果返回的是另外一个新promise, 此promise 的结果就成为新promise的结果
<script> //1. 创建一个promise let p = new Promise((reosolve, reject) => { reosolve('ok') }) console.log('p:', p) //2.执行then方法 let result = p.then((ref) => { console.log(ref) //1.抛出错误 // throw '抛出异常' //2.返回结果是 非promise 类型的对象 // return 521 //3.返回结果是 一个promise 对象 return Promise.resolve('Success') }, (reason) => { console.log(reason); }) console.log('result:', result) </script>
结果
![]()
4、promise 如何串联多个操作任务?
⏰ 1. promise 的 then() 返回一个新的promise, 可以开成then()的链式调用
<script> //1. 创建一个promise let p = new Promise((resolve, reject) => { setTimeout(()=> { resolve('ok') }, 1000) }) //2.then的链式操作 p.then((ref) => { return new Promise((resolve, reject) => { resolve('success') }) }).then((value) => { console.log(value) }) </script>
结果

⏰ 2.通过then的链式调用串联多个同步/异步任务
- 同步任务
let p = new Promise((resolve,reject)=>{ resolve('ok') }).then((reason)=>{ console.log(111); }).then((reason)=>{ console.log(222); }).then((reason)=>{ console.log(333) }).then((reason)=>{ console.log(444) })
结果
111 222 333 444
- 异步任务
let p = new Promise((resolve, reject) => { resolve('ok') }).then((reason) => { console.log(111); return new Promise((resolve, reject) => { setTimeout(() => { resolve('ok') }, 1000) }) }).then((reason) => { console.log(222); return new Promise((resolve, reject) => { setTimeout(() => { resolve('ok') }, 1000) }) }).then((reason) => { console.log(333) return new Promise((resolve, reject) => { setTimeout(() => { resolve('ok') }, 1000) }) }).then((reason) => { console.log(444) return new Promise((resolve, reject) => { setTimeout(() => { resolve('ok') }, 1000) }) })
结果
111 222 333 444
5、promise 异常透传?
⏰ 1. 当使用promise 的then链式调用时,可以在最后指定失败回调
let p = new Promise((resolve, reject) => { console.log(111) reject('err') }).then((ref) => { console.log(222) }).then((ref) => { console.log(222) }).then((ref) => { console.log(222) }).catch((reason) => { console.log(reason) })
打印结果
111 err
⏰ 2. 当前任何操作出了异常, 都会传到最后失败的问题中处理
let p = new Promise((resolve, reject) => { setTimeout(() => { resolve('ok') }, 1000) }).then((ref) => { console.log(111) }).then(() => { console.log(222) throw ('出错了2') }).then(() => { console.log(333) }).catch((err) => { console.log('catch', err); })
打印结果:
111 222 catch 出错了2
⏰ 3. Promise 的 error 是如何在链式调用中向下传递的并被处理的呢?答案是: 隐式的 try…catch
通常,一遇到异常抛出,浏览器就会顺着 Promise 链寻找下一个就近的 onRejected 失败回调函数或者由 .catch() 指定的回调函数。你可以想象成 promise 的整个执行器(executor)和 promise 的处理程序周围有一个隐式的 “try...catch”。
这一错误的传递就被称为 promise 的异常穿透。
let p = new Promise((resolve, reject) => { reject('失败了') }).then((ref) => { console.log('onResolve', ref); }, (err) => { console.log('onReject', err) }).catch((err) => { console.log('catch', err); })
结果
onReject 失败了
上述例子中,"失败了" 就会被离它最近的 then 中的 onRejected 函数所处理,而不会被 catch 所捕获。
6、中断promise链条?
当使用promise 的then链式调用时,在中间中断,不再调用后面的回调函数
⏰ 办法:在回调函数中反应一个pendding状态的promise 对象。只有这一个办法!
let p = new Promise((resolve, reject) => { setTimeout(() => { resolve('ok') }, 1000) }).then((ref) => { console.log(111) }).then(() => { console.log(222) return new Promise(()=>{}) }).then(() => { console.log(333) }).then(() => { console.log(444) })
结果
111 222






浙公网安备 33010602011771号