目录
1.JavaScript同步任务、异步任务
1.1单线程
- 首先JS是单线程语言(H5中提到的Web-Worker可以实现多线程效果等后续有精力在了解…)
- 单线程就意味着在按照执行栈中的任务顺序依次执行(同步任务),如果单个任务执行时间过长,后面任务就要一直卡死,为了解决这个情况,异步任务应运而生
1.2同步任务、异步任务执行过程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-80WX0Qyl-1588935610497)(https://user-gold-cdn.xitu.io/2020/5/7/171ee64be4de4bc0?w=1148&h=960&f=png&s=401302)]
- 1.形成js执行栈,整个代码片为一个宏任务
- 2.按照执行栈中同步任务的顺序依次执行
- 3.碰到异步任务,就在任务队列中增加一个任务事件
- 4.等到执行栈为空,开始将任务队列中的异步任务结束等待,入栈执行(从任务队列里找到最先入队的任务)
- 5.结束执行,内存资源释放
- 依次循环2.3.4执行,这个过程称为EventLoop
2.EventLoop
2.1宏任务
- script全部代码
- setTimeout
- setInterval
- setImmediate
- I/O操作
- UI界面渲染
2.2微任务
- Promise
- Process.nextTick(Node独有)
- MutationObserver
3.Promise
3.1 什么是promise
- 异步编程的一种解决方式
- 一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果
- 从语法上说,Promise 是一个对象,从它可以获取异步操作的消息
- 对象状态不受外界影响,只会根据异步操作的结果决定
- pending(进行中)
- fulfilled(成功)
- rejected(拒绝)
- resolved(结束)
- 一旦改变,就不会再变
- pending -> fulfilled
- pending -> rejected
- 不能取消,一旦新建就会立即执行
- pending状态下无法得知进行状态(是刚开始还是快要完成了)
- 如果不设置回调函数,会在内部抛出错误
- 对象状态不受外界影响,只会根据异步操作的结果决定
3.2 promise 怎么用
3.2.1 Promise对象是一个构造函数,用来生成Promise实例
const promise = new Promise((resolve,reject)=>{
if(//异步执行成功调用resolve函数){
resolve(value)
}else{
//异步执行失败调用reject函数
reject(value)
}
})
- 通常生成promise实例后,通过then方法指定resolved和rejected状态的回调函数
- 第一个参数为resolve的回调函数,必填(不指定执行成功后的回调函数在promise实例内会抛出异常),第二个参数reject的回调函数是可选的(一般不定义在then函数中,一般在then后链式调用catch)
//不推荐
promise.then(
//第一个参数为resolve的回调函数,必填,第二个参数reject的回调函数是可选的,我们不推荐这样写
(value)=>{//resolve 成功},
(value)=>{//reject 失败}
)
//推荐写法
promise.then(data=>{
//resolve
}).catch(err=>{
//reject
//此处不catch的话,外部是不会有报错的,即不会捕获promise实例reject的状态
})
4.async…await
4.1 什么是async
- async修饰的函数内会有异步任务,需要等待await修饰的函数执行完在继续执行其他语句
- async函数可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖
- async函数内任何一个await语句返回reject,后面的语句都不会执行
- 解决办法:await放到try…catch语句中
- 本质为generator的语法糖
4.2 什么是await
-
await返回一个promise对象,如果修饰的不是promise对象就返回其值
-
不能单独使用,必须配合async
-
不存在继发关系,最好让它们同时触发
- 实现方式:
let [foo, bar] = await Promise.all([getFoo(), getBar()]);