JS执行机制

 1.同步和异步

同步与异步是指访问数据的机制,同步一般指主动请求并等待IO操作完成的方式。

异步则指主动请求数据后便可以继续处理其它任务,随后等待IO操作完毕的通知

同步和异步最大的区别就在于:同步需要等待,异步不需要等待

同步请求存在着两个明显的缺陷:

① 请求发出后必须要等待响应

比如当遇到请求阻塞,网络延迟等情况时,用户需要进行等待,这样会导致用户体验效果差。

② 每次请求都需要重新加载整个页面

比如在访问某个页面时,有的时候用户可能只需要请求获取页面某一部分内容的响应,但是当用户发送请求后,整个页面的所有内容都需要重新加载后再响应给用户,这样同样会导致用户的体验较差。

2.宏任务与微任务

在当前的微任务没有执行完成时,是不会执行下一个宏任务的。

setTimeout(_ => console.log(4),0)

new Promise(resolve => {
  resolve()
  console.log(1)
}).then(_ => {
  console.log(3)
})

console.log(2)

setTimeout就是作为宏任务来存在的,而Promise.then则是具有代表性的微任务

所有会进入的异步都是指的事件回调中的那部分代码
也就是说new Promise在实例化的过程中所执行的代码都是同步进行的,而then中注册的回调才是异步执行的。
在同步代码执行完成后才回去检查是否有异步任务完成,并执行对应的回调,

而微任务又会在宏任务之前执行(因为微任务实际上是宏任务的其中一个步骤).
所以就得到了上述的输出结论1、2、3、4

+部分表示同步执行的代码

+setTimeout(_ => {
-  console.log(4)
+})

+new Promise(resolve => {
+  resolve()
+  console.log(1)
+}).then(_ => {
-  console.log(3)
+})

+console.log(2)

本来setTimeout已经先设置了定时器(相当于取号),然后在当前进程中又添加了一些Promise的处理(临时添加业务)。

所以进阶的,即便我们继续在Promise中实例化Promise,其输出依然会早于setTimeout的宏任务:

setTimeout(_ => console.log(4))

new Promise(resolve => {
  resolve()
  console.log(1)
}).then(_ => {
  console.log(3)
  Promise.resolve().then(_ => {
    console.log('before timeout')
  }).then(_ => {
    Promise.resolve().then(_ => {
      console.log('also before timeout')
    })
  })
})

console.log(2)

实际情况下很少会有简单的这么调用Promise的,一般都会在里边有其他的异步操作,比如fetchfs.readFile之类的操作。
而这些其实就相当于注册了一个宏任务,而非是微任务。

async/await函数

async/await本质上还是基于Promise的一些封装,而Promise是属于微任务的一种。

所以在使用await关键字与Promise.then效果类似:

setTimeout(_ => console.log(4))

async function main() {
  console.log(1)
  await Promise.resolve()
  console.log(3)
}

main()

console.log(2)

async函数在await之前的代码都是同步执行的,可以理解为await之前的代码属于new Promise时传入的代码,await之后的所有代码都是在Promise.then中的回调

宏任务

#浏览器Node
I/O
setTimeout
setInterval
setImmediate
requestAnimationFrame

微任务

#浏览器Node
process.nextTick
MutationObserver
Promise.then catch finally

相关面试题

JS执行机制是从上到下执行,同步代码优先异步代码,微任务优先宏任务执行

  async function async1() {
    console.log('async1 start')
    await async2()
    console.log('async1 end') // 相当于promise.then的异步回调
  }

  async function async2() {
    console.log('async2')
  }

  console.log('script start')

  setTimeout(function () {
    // 定时器作为宏任务的存在
    console.log('setTimeout')
  }, 0)

  async1()

  new Promise(function (resolve) {
    console.log('promise1')
    resolve()
  }).then(function () {
    console.log('promise2')
  })
  console.log('script end')

  // 'async1 start'
  // 'script start'
  // 'async2'
  // 'promise1'
  // 'script end'
  // 'async1 end'
  // 'promise2'
  // 'setTimeout'

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值