前言
Promise是JS中的一个内置类
基础写法
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Promise基础语法</title> </head> <body> <script> let ran = Math.random() let promiseExamp = new Promise((resolve, reject) => { setTimeout(() => { ran < 0.5 ? reject(ran) : resolve(ran) }, 1000) }) promiseExamp.then((result) => { console.log('成功:' + result) }, (error) => { console.log('失败:' + error) }) </script> </body> </html>
Promise的executor函数和状态
Promise的状态
- pending 初始状态(NEwPROMISE后的状态)
- fulfilled 操作成功完成(在executor函数中把resolve执行,就是告知promise当前异步操作的结果是成功的)
- rejected 操作失败(在executor函数中把reject执行,就是告知promise当前异步操作的结果是失败的)
executor函数
- let pro = new Promise([executor])
- new Promise 的时候就会把
执行函数[executor]
执行,[executor]是Promise类的一个回调函数,Promise内部会把它执行。 - Promise不仅将它执行,还给他传递两个参数(两个参数也是函数类型)
- resolve函数:如果它执行,就代表Promise处理的异步事情是成功的,将Promise的状态由
padding --改为--> fulfilled
- reject函数:如果它执行,就代表Promise处理的异步事情是失败的,将Promise的状态由
padding --改为--> rejected
- [executor]函数中所放的就是当前要处理的异步操作事情(同步也是可以的,但一般存放的是异步任务),任务成功,执行resolve,任务失败执行reject
Promise中的then和catch和finally方法
重点不是要知道异步任务是成功还是失败,而是要确定失败之后做什么,成功之后做什么
- Promise.prototype 上
- then 设置
成功
或者失败
后执行的方法(成功或者失败都可以设置,也可以只设置一个)当执行到异步操作时,主线程不会等待异步执行完成,而是先基于then方法将我们要在成功或者失败的时要执行的东西扔到事件池中,暂时是不执行的,而是等待状态更改后的通知安排。
- promiseExamp.then([success],[error])
- promiseExamp.then([success])
- promiseExamp.then(null,[error])
- catch: 设置失败后执行的方法
- finally: 设置不论成功还是失败都会执行的方法(一般很少用)
then 链
执行then/catch/finally返回的结果是一个全新的Promise实例,所以可以链式写下去,下一个then中哪个方式会被执行,由上一个then中某个方法的执行结果来决定
<script> let pro1 = new Promise((resolve, reject) => { setTimeout(() => { let ran = Math.random() ran < 0.5 ? reject(ran) : resolve(ran) }, 1000) }) let pro2 = pro1.then(result => { console.log('pro1:success'); }, error => { console.log('pro1:error'); }) let pro3 = pro2.then(result => { console.log('pro2:success'); }, error => { console.log('pro2:error'); }) </script>
---控制台的打印情况--- 第一种:ran小于0.5时 pro1:error pro2:success 第二种:ran大于0.5时 pro1:success pro2:success
一个then中某个方法的的返回值会返回给下一个then的某个方法中
<script> new Promise((resolve, reject) => { resolve(100) //=> 将第一个Promise实例的Value值改为100 }).then(result => { console.log(result); return result * 10 //=> then中return的结果相当于把当前这个新的promise实例中的value值改为返回值 }, error => { console.log(error); }).then(A => { console.log(A); }, B => { console.log(B); }).then(C => { console.log(C) },D => { console.log(D) }) </script>
---控制台--- 100 1000 undefined
以上便是PROMISE里的分量机制,每一次then后,都会是一个新的PROMISE实例,该实例只受上一个PROMISE实例影响(上一个实例的状态和value值来决定)
我们再来看PROMISE的玩法
如果如果当前PROMISE实例状态确定后,都会找到对应的THEN中找方法,如果THEN中没有对应的这个方法,则会向下顺延
new Promise(resolve,reject) => { reject(-100) }.then(A => { console.log(A) return A * 10 }).catch(B => { console.log(B) return B * 10 })
---控制台--- -100
new Promise(resolve,reject) => { resolve(100) }.then(A => { console.log(HELLO) return A * 10 }).catch(B => { console.log(B) }).then(C => { console.log('日闽好帅') })
---控制台--- ReferenceError: HELLO is not defined 日闽好帅
通过这个PROMISE实例身上的.catch方法,它能够带来什么好处呢?
我们通过上面的两个示例,可以看到.catch所能够监视到的范围变大了,如果第一个PROMISE实例它的状态修改为失败,而第二个PROMISE实例中并没有设置第二个接受失败的回调,因此顺延到第三个.catch创建的PROMISE实例对象来执行;如果第一个PROMISE实例它的状态修改为成功,但是第二个PROMISE实例的成功回调中处理失败,将状态改为了rejected,那么就以该报错原因作为VALUE值,.catch即是可以接受其报错原因,也是可以进行失败后的一些操作的,如果这样写,就可以监听到两个了,是不是很不错的选择。
我们来看一道题目,它的打印结果是什么?
new Promise((resolve,reject) => { resolve(); }).then().catch(x => { console.log(1) }).then(x => { console.log(2) // => ok }).then(x => { console.log(3) // => ok }).catch(x => { console.log(4) }).then(x => { console.log('AAA') // => ok console.log(AAA) // => 报错 }).catch().then(null, x => { console.log(5) // => ok })
---控制台--- 2 3 AAA 5
谢谢款待
小记整理于 2023
/ 12
/ 31