关于javascript:JS执行机制与Event-LoopSDK社区

40次阅读

共计 3509 个字符,预计需要花费 9 分钟才能阅读完成。

前言

整顿了一下 javascript 的基础知识,在此给大家做下分享,喜爱的大佬们能够给个赞。

js 是一门单线程语言。js 引擎有一个主线程(main thread)用来解释和执行 js 程序,实际上还存在其余的线程。例如:解决 ajax 申请的线程、解决 DOM 事件的线程、定时器线程、读写文件的线程 (例如在 node.js 中) 等等。这些线程可能存在于 js 引擎之内,也可能存在于 js 引擎之外,在此咱们不做辨别。无妨叫它们工作线程。

JS 执行上下文

当代吗运行时,会产生对应的运行环境,在这个环境中,所有的变量都会备实现提出来(变量晋升),有的间接赋值,有的默认赋值,有点默认值 undefined,代码从上而下开始执行,就叫做执行上下文。

1、变量晋升

foo // undefined
var foo = function () {console.log('foo1')
}

foo() // foo1, foo 赋值

var foo = function () {console.log('foo2')
}

foo() // foo2, foo 赋值

2、函数晋升

foo() // foo2
function () {console.log('foo1')
}

foo() // foo2

function foo () {console.log('foo2')
}
foo() // foo2

3、申明优先级,函数 > 变量

foo() // foo2
var foo = function () {console.log('foo1')
}

foo() // foo1, foo 从新赋值

function foo () {console.log('foo2')
}

foo() // foo1

运行环境

在 javascript 的世界中,运行环境有三种,别离是:

1、全局环境:代码首先进入环境
2、函数环境:函数被调用时执行的环境
3、eval 函数:(不罕用)

执行上下文特点

1、单线程,在主线程上进行
2、同步执行,从上往下按程序执行
3、全局上下文只有一个,浏览器敞开时会被弹出栈
4、函数执行上下文没有数目限度
5、函数每被调用一次,都会产生一个新的执行上下文环境

执行上下文栈

执行全局代码时,会产生一个执行上下文环境,每次调用函数都又会长生一个执行上下文环境。当函数调用实现时,这个上下文环境以及其中的数据都会被打消,再从新回到全局上下文环境,处于活动状态的执行上下文环境只有一个。

其实这是一个压栈出栈的过程————执行上下文栈

var // 1. 进入全局上下文环境
  a = 10,
  fn,
  bar = function (x) {
    var b = 20
    fn(x + b) // 3. 进入 fn 上下文环境
  }

fn = function (y) {
  var c = 20
  console.log(y + c)
}

bar(5) // 2. 进入 bar 上下文环境

执行上下文的生命周期

1、创立阶段

  • 生成变量对象
  • 建设作用域链
  • 确定 this 指向

2、执行阶段

  • 变量赋值
  • 函数援用
  • 执行其余代码

3、销毁阶段

  • 执行出栈结束,期待回收被销毁

javascript 事件循环

  • 同步和异步工作别离进入不同的执行“场合”,同步的进入主线程,异步的进入 Event Table 并注册函数
  • 当指定事件实现时,Event Table 会将这个函数移入 Event Queue
  • 主线程内的工作执行结束为空,会去 Event Queue 读取对应的函数,进入主线程执行
  • 上述过程会一直反复,也就是常说的 Event Loop(事件循环)

同步工作和异步工作,咱们对工作有更精密的定义:

macro-task(宏工作)

能够了解是每次执行栈执行的代码就是一个宏工作(包含每次从事件队列中获取一个事件回调并放到执行栈中执行)

浏览器为了可能使得 JS 外部 (macro)task 与 DOM 工作可能有序执行,会在一个 (macro)task 执行完结后,在下一个 (macro)task 执行开始前,对页面进行从新渲染

(macro)task 次要蕴含:script (整体代码)、setTimeout、setInterval、I/O、UI 交互事件、postMessage、MessageChannel、setImmediate(Node.js 环境)

micro-task(微工作)

能够了解是在以后 task 执行完结后立刻执行的工作。也就是说,在以后的 task 工作后,下一个 task 之前,在渲染之前。所以他的响应熟读比 setTimeout 会更快,因为无需等渲染。也就是说,在摸一个 macrotask 执行完后,就会将在它执行期间产生的所有 mocrotask 都执行结束(在渲染前)。

macrotask 次要包含:Promise.then、MutaionObserver、process.nextTick(Node.js 环境)

举个例子

咱们来剖析一段比较复杂的代码,看看你是否真的把握了 js 的执行机制

consoloe.log('1')

setTimeout(function () {console.log('2')
  process.nextTick(function () {console.log('3')
  })
  new Promise(function (resolve) {console.log('4')
    resolve()}).then(function () {console.log('5')
  })
})

process.nextTick(function () {console.log('6')
})

new Promise(function (resolve) {console.log('7')
  resolve
}).then(function () {console.log('8')
})

setTimeOut(function () {console.log('9')
  process.nextTick(function () {console.log('10')
  })
  new Promise(function (resolve) {console.log('11')
    resolve()}).then(function () {console.log('12')
  })
})
// 1, 7, 8, 2, 4, 5, 6, 3, 9, 11, 12, 10

又一个例子

async function async1 () {console.log('async1 start')
  await async2()
  console.log('async1 end')
}

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('sacript end')

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

解决异步的办法

1、回调函数

ajax('x1', () => {
  // callback 函数体
  ajax('x2', () => {
    // callback 函数体
    ajax('x3', () => {// callback 函数体})
  })
})
  • 长处:解决了同步的问题
  • 毛病:回调天堂,不能用 try catch 捕获谬误,不能 return

2、Promise 为了解决 callback 的问题而产生

Promise 实现了链式调用,也就是说每次 then 后返回的都是一个全新的 Promise,如果咱们在 then 中 return,return 的后果会被 Promise.reolve() 包装

  • 长处:解决了回调天堂
  • 毛病:无奈勾销 Promise,谬误须要通过回调函数来捕捉

3、Async/await

  • 长处是:代码清晰,不必 Promise 写一大堆 then 链,解决了回调天堂问题
  • 毛病:await 将异步代码革新成同步代码,如果多个异步操作没有依赖性而应用 await 会导致性能上的升高

总结

  • javascript 是一门单线程语言
  • Event Loop 是 javascript 的执行机制

原文链接:https://www.sdk.cn/details/eqZPyk7Agy4eb5QxXw

SDK 社区 是一个中立的社区,这里有多样的前端常识,有丰盛的 api,有爱学习的人工智能开发者,有有趣风趣的开发者带你学 python,还有将来炽热的鸿蒙,当各种元素组合在一起,让咱们一起脑洞大开独特打造业余、好玩、有价值的开发者社区,帮忙开发者实现自我价值!

正文完
 0