一、同步、异步
同步是阻塞模式,指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;
(简单理解同步就是有顺序的从先到后执行,前一个进程没有执行完,后一进程只有等待前面的执行完后,才可以继续执行)
异步是非阻塞模式,指这个进程不需要一直等待下去,而是继续执行之后的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率以及节约时间。
(简单理解异步就是多个进程执行时不用等待其他进程执行完毕的要求,继续执行之后的操作,有消息返回时再通知进程进行处理,相当于多个任务直接同时进行)
二、同步任务、异步任务
JavaScript是一门单线程语言,也就是同一时间只可以做一件事情,如果前一个任务非常耗时,则后续任务就必须得一直等待下去,从而导致 程序假死 的问题,为了解决程序假死,JavaScript把任务认为了两类
1、同步任务(synchronous)
也叫非耗时任务,指在主线程上排队执行的那些任务
前一任务执行完毕后,才可以执行后一任务才
2、异步任务(asynchronous)
也叫耗时任务,不是由JavaScript执行,而是由JavaScript委托给宿主环境(浏览器、node)进行执行
当异步任务执行完成后,会通知JavaScript的主线程执行异步任务的回调函数
异步任务又分为宏任务(macrotask)和微任务(microtask),宏任务包括异步Ajax请求、setTimeout延时器与setInterval定时器、文件操作···,而微任务则是Promise.then() \ .cath()\ .finally、process.nextTick···
三、同步任务和异步任务的执行过程
同步任务是由JavaScript主线程依次序执行,而异步任务委托给宿主环境去执行,已完成的异步任务对应的回调函数,会被加入到任务队列中等待执行,JavaScript主线程上的执行栈被清空后,主线程从任务队列中读取异步函数的回调函数,放到执行栈中依次序执行,这个读取再执行的过程是循环不断的,这种运行机制又称为EventLoop(事件循环)
四、任务执行顺序
现在主要细分为同步任务、宏任务、微任务,
个人理解思想:
先执行同步任务,再执行微任务,后执行宏任务
注意是在一个大的作用域之内去比较
遇到代码,从最外层作用域层层向内剖析任务类别,如console.log()、new Promise()之类,先将这种同步任务执行,再去看他们身上是否存在微任务,如new Promise()上的then()方法、.catch()方法,如果有,先将此微任务依次放入宿主环境等待执行,所有的同步任务限制先执行完后,再执行等待中的微任务,微任务完之后执行宏任务。
注意点:
1、执行下一个宏任务之前,必须先将之前的所有微任务都执行完毕。
2、new Promise((resolve,reject)=>{
resolve('成功')
})
Promise构造函数中没有resolve或者reject输出,之后的.then()方法是不可执行的,
3、async下的await会使当前以及之后的输出变为微任务,注意是同一作用域
特殊情况: await 函数名() ,这个情况下
此函数是同步任务,之后的代码为微任务
测试
console.log('1')
setTimeout(function () {
console.log('2')
new Promise(function (resolve) {
console.log('3')
resolve()
}).then(function () {
console.log('4')
})
})
new Promise(function (resolve) {
console.log('5')
resolve()
}).then(function () {
console.log('6')
})
setTimeout(function () {
console.log('7')
new Promise(function (resolve) {
console.log('8')
resolve()
}).then(function () {
console.log('9')
})
})
输出结果在评论区