Promise
1.Promise的前置知识
-
进程(厂房)
- 程序的运行环境
-
线程(工人)
- 线程是实际进行运算的东西
-
同步
- 通常情况代码都是自上向下一行一行执行的
- 前边的代码不执行后边的代码页不会执行
- 同步的代码执行会出现阻塞的情况
- 一行代码执行慢会影响到整个程序的执行
-
解决同步的问题:
-
java python
- 通过多线程来解决,但是一般消耗资源比较多
-
node.js
-
通过异步方式来解决
我们可以这么理解:客人就好比我们请求的数据,服务员就好比客户端,厨师就好比服务器,我们现在客人点菜,服务员接收到菜的名称信息,给厨师说,厨师开始做,厨师在做的时候,客人一直等,不能干其他的事情,这就是同步,只能干一件事,我们现在利用异步的方式,可以让客人在课桌上等着菜来,也不影响服务员接收下一个客人的点菜,这样就可以很好的处理同步所带来的堵塞问题
-
-
-
异步
-
一段代码的执行不会影响到其他的程序
-
异步的问题:
- 异步的代码无法通过
return
来设置返回值
- 异步的代码无法通过
-
特点:
-
不会阻塞其他代码的执行
-
需要通过回调函数来返回结果
function sum(a, b, cb) { setTimeout(() => { cb(a + b) //调用箭头函数,把结果作为回调函数的参数 }, 1000) } sum(123, 456, (result)=>{ console.log(result) })
-
-
基于回调函数的异步带来的问题
-
代码的可读性差
-
可调试性差(造成回调地狱)
sum(123, 456, (result)=>{ sum(result, 7, (result)=>{ sum(result, 8, result => { sum(result, 9, result => { sum(result, 10, result => { console.log(result) }) }) }) }) })
-
-
解决问题:
- 需要一个东西,可以代替回调函数来给我们返回结果
Promise
横空出世- Promise是一个可以用来存储数据的对象
- Promise存储数据的方式比较特殊,这种特殊的方式使得Promise可以用来存储异步调用的数据
- Promise是一个可以用来存储数据的对象
-
2.Promise介绍
异步调用必须要通过回调函数来返回数据,当我们进行一些复杂的调用时,会出现回调地狱
问题:
异步必须通过回调函数来返回结果,回调函数增加就不容易处理
- Promise
- Promise可以帮助我们解决异步中的回调函数的问题
- Promise就是一个用来存储数据的容器
- 它拥有着一套特殊的存储数据的方式
- 这个方式使得它里面可以存储异步调用的结果
-
创建Promise
-
创建Promise时,构造函数中需要一个函数作为参数
-
Promise构造函数的回调函数,它会在创建Promise时调用,调用时会有两个参数传递进去
const promise = new Promise((resolve, reject)=>{ // resolve 和 reject 是两个函数,通过这两个函数可以向Promise中存储数据 // resolve 在执行正常的时候存储数据, reject 是在执行错误的时候存储数据 resolve('我是正常执行的时候调用的') reject('我是错误执行的时候调用的') //通过函数来访问Promise中添加数据,好处就是可以用来添加异步调用的数据 setTimeout(()=>{ resolve('异步中调用数据') },2000) throw new Error('出错了,调用的是reject') })
-
-
从Promise中读取数据
-
可以通过Promise的实例方法
then
来读取Promise中存储的数据 -
then需要两个回调作为参数,回调函数来获取Promise中的数据
-
通过resolve存储的数据,会调用第一函数返回,可以在第一个函数中编写处理数据的代码
-
通过reject存储数据或者出现异常时,会调用第二个函数返回,可以在第二个函数中编写处理异常的代码
promise.then((result)=>{ console.log('1',result) },(reson)=>{ console.log('2',reason) })
-
-
-
Promise中维护了两个隐藏属性:
- PromiseResult
- 用来存储数据
- PromiseState
- 记录Promise的状态(三种状态)
pending
(进行中)fulfilled
(完成)通过resolve存储数据时rejected
(拒绝,出错了)出错了或通过reject存储数据时
- state只能修改一次,修改以后永远不会在变
- 记录Promise的状态(三种状态)
- 流程:
- 当Promise创建时,PromiseState初始值为pending
- 当通过resolve存储数据时 PromiseState 变为fulfilled(完成)
- PromiseResult变为存储的数据
- 当通过reject存储数据或出错时 Promise 变为rejected(拒绝)
- PromiseResult变为存储的数据 或 异常对象
- 当通过resolve存储数据时 PromiseState 变为fulfilled(完成)
- 当我们通过then读取数据时,相当于为Promise设置了回调函数
- 如果PromiseState变为fulfilled,则调用then的第一个回调函数来返回数据
- 如果PromiseState变为rejected。则调用then的第二个回调函数来返回数据
- 当Promise创建时,PromiseState初始值为pending
const promise2 = new Promise((resolve, reject) => { resolve("哈哈") }) // console.log(promise2) promise2.then(result => { console.log(result) }, reason => { console.log("出错了") })
- PromiseResult
-
catch()
用法和then类似,但是只需要一个回调函数作为参数-
catch() 中的回调只会在Promise被拒绝时才会调用
-
catch() 相当于 then(null, reason=>{})
-
catch() 就是一个专门处理Promise异常的方法
promise2.catch(reason => { console.log(222222) })
-
-
finally()
-
无论是正常存储数据还是出现异常了,finally总会执行
-
但是finally的回调函数中不会接收到数据
-
finally()通常用来编写一些无论成功与否都要执行的代码
promise2.finally(()=>{ console.log("没有什么能够阻挡我执行的!") })
-