简述ES6新增的语法三(回调函数和Promise以及asyncawait关键字)
什么是JS中的回调函数?
回调函数:
运⾏某个函数实现某个功能的时候,传⼊⼀个函数作为参数,当发⽣某件事情的时候,会执⾏该函数 这个函数参数就是回调函数
回调地狱:
某个异步操作需要等待之前的异步操作完成,⽆论回调是事件还是其他函数,都会陷⼊不断的嵌套
通过回调函数异步操作 某个异步操作要等待别的操作对他的结果,这种联系的处理,会让代码的复杂度急剧增加
promise
promise简介
ES官⽅参考了⼤量的异步场景,总结出了⼀套异步通⽤的模型,这套模型可以覆盖⼏乎所有的异步场景
ES6中增强的功能,ES为了兼容以前的版本,以前旧的写法并没有抛弃,针对这些场景推出了新的API,这套API对异步的处理,变得更为简洁
将某⼀件事情可以发⽣异步操作的时候,分为了2个阶段 unsettled 和 settled
unsettled未决阶段
settled已决阶段
事情总是从 未决阶段逐步发展到已决阶段,并且,未决阶段拥有控制通往已决阶段的能⼒
es6将程序分为了三种状态 pending resolved rejected
pending:挂起(等待) 处于未决阶段,表⽰事情还是在挂起,最后的结果没有出来
resolved:已处理 处于已决阶段,表⽰整个事情已经出现结果,并且可以按照正常的逻辑进⾏下去的结果
rejected:已拒绝 处于已决阶段,表⽰整个事情已经出现结果,并且是⼀个⽆法按照正常逻辑进⾏下去的结果
未决阶段有权利决定事情的⾛向,未决阶段可以决定事情⾛向最终的状态
把事情推向resolved 状态的过程,可能会传递⼀些数据
把事情推向resolved 状态的过程,可能会传递⼀些数据,这些数据⼀般为错误信息
⽆论是哪个阶段还是状态,都是不可逆的
当事情已经到达已决阶段后,通常要进⾏后续的处理,不同的已决解决,决定了不同的后续处理
resolved 这是⼀个正常的已决状态,后续处理表⽰为 thenable
rejected 这是⼀个⾮正常的已决状态,后续处理表⽰为 catchable
后续的处理可能会有多个,因此会形成任务队列,这些后续处理会按照顺序,当达到对应的状态后依次执⾏
Promise 的⽅法
是异步编程的⼀种解决⽅法,其实是⼀个构造函数 ⾃⼰⾝上有ject,resolve 这⼏个⽅法 ,原型上有then,catch等⽅法
语法:
只要new Promise()就可以,并且接受⼀个函数,该函数⾥⾯会执⾏resolve()⽅法,表⽰异步调⽤成功时执⾏,reject()表⽰异步调⽤失败时候调⽤
未决阶段
通过调⽤resolve函数将promise推向已决阶段的resolve状态
通过调⽤reject函数将promise推向已决阶段的reject状态通常使⽤throw
resolve 和 reject 只能使⽤⼀个,如果使⽤了多个,也只有第⼀个有⽤
传递参数只能有⼀个,表⽰推向状态的数据
resolve({})或者reject(456)
const pro = new Promise((resolve,reject) => {
resolve(456)
reject(123)//throw 作⽤⼀样都是推向失败
})
then⽅法
pro.then(data=>{
thenable函数,promise已经是已决阶段,resolve状态
},err => {
catchable函数 reject状态
})
catch()⽅法
pro.catch(err => {
catchable函数 reject状态
console.log(err)
})
Promise 特点
1.未决阶段的处理函数是同步的,会⽴即执⾏
2.如果当前的promise是未决的,得到的新的promise是挂起状态
3.在未决阶段的处理函数中,如果发⽣未补获的错误,会将状态推向rejected,并且会被catchable捕获
4.⼀旦状态推向了已决阶段,⽆法再去做任何的改变
5.thenable和catchable函数是异步的,就算会⽴即执⾏,也是会加⼊等待队列中,加⼊微队列
6.pro.then可以只添加thenable函数,pro.catch可以单独添加catchable函数
7.如果前⾯的promise的后续处理,返回的是⼀个promise,则返回的promise状态和后续处理返回的promise状态保持⼀致
8.Promise并不是消除回调,只是让回调变得更简单,变更可控
Promise 原型成员(实例成员)
1.then(data => {},err => {})
注册⼀个后续处理函数,当promise为resolved状态是运⾏该函数,当promise为rejected状态是运⾏该函数的第⼆个参数
2.catch() 注册⼀个后续处理函数,当promise为rejected状态是运⾏该函数,习惯把失败写在catch中
3.finally() ES2018出来的,没有参数的,当promise为已决时运⾏该函数 先写先执⾏ 后写后执⾏
const pro = new Promise((resolve,reject) => {
resolve(1)
})
pro.finally(() => {
console.log('finally')
})
pro.then(result => {
console.log('then',result * 2)
})
Promise构造函数成员(静态成员)
const pro = solve(1)
//等同于
// 推向了完成阶段的成功状态
const pro = new Promise((resolve,reject) => {
resolve(1)
})
const pro = ject(1)
//等同于
//推向了完成阶段的失败状态
const pro = new Promise((resolve,reject) => {
reject(1)//throw 作⽤⼀样都是推向失败
})
特殊情况:如果传递的是Promise,则直接返回传递的Promise对象(原封不动的)
const pro = new Promise((resolve,reject) => {
resolve(123)
})
const pro2 = solve(pro)
console.log(pro2 === pro) true
3.all(arr) 这个⽅法会返回⼀个新的promise对象,如果⾥⾯所有的promise对象都成功才会触发,
⼀旦有⼀个失败,则该promise对象为失败
4.ace(arr) 当参数中的任意⼀个promise对象完成时候,就马上回去使⽤完成的这个
promise对象的结果,不管这个结果成功还是失败
在ES2016中新增了两个关键字 async await 为了去简化promise的写法的
async 简化promise创建的声明⼀异步任务(async function 对象)
⽤于去修饰函数(函数声明和函数表达式),放在函数的开始位置,被修饰的函数⼀定返回⼀个promise对象,可以使⽤then⽅法添加回调函数。当函数执⾏的时候,⼀旦遇到await就会先返回,等到异步操作完成,再接着执⾏函数体内后⾯的语句。
await和async使用方法async function test(){
//return 123;//resolve成功的数据
throw 123//reject失败的数据
}
const pro = test();
console.log(pro)
//等同于
const pro = new Promise((resolve,reject) => {
resolve(123);
reject(123);
}
await 等待(指的是等待⼀个异步任务执⾏完成的结果) await 必须出现在async函数中
function test1(){
return new Promise((resolve,reject) => {
resolve(123)
})
}
function test2(){
return new Promise((resolve,reject) => {
test1().then(data => {
const result = data;
console.log(result);
resolve()
})
})
}
test2()
// 等同于
async function test1(){
return 123;
}
async function test2(){
const result = await test1(); // test1()被async修饰的函数被当作
console.log(result)
}
test2()
正常情况下,await命令后⾯是⼀个 Promise 对象,返回Promise对象的结果。如果await的表达式不是Promise,则会对包装⼀个promise继续按照规则执⾏
await使⽤注意点
1.正常情况下await命令后⾯修饰的Promise对象,返回Promise对象的结果可能是rejected 错误数据,就不会执⾏await语句,所以最好把await命令放在try…catch代码块中。
2.await命令只能⽤在async函数之中,如果⽤在普通函数,就会报错。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论