Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS执行机制 —— 一名【合格】前端工程师的自检清单答案整理 #6

Open
akeymo opened this issue Dec 21, 2019 · 0 comments

Comments

@akeymo
Copy link
Owner

akeymo commented Dec 21, 2019

执行机制

为何try里面放return,finally还会执行,理解其内部机制

try-catch的执行机制里,如果try或者catch中有return,都会先执行finally里的代码,并且finally里没有return才会去执行try或者catch里的return,例如:

function test1() {
  try {
    console.log(1);
    throw new Error('throw');
  } catch (e) {
    console.log(e.message);
    return 'from_catch';
  } finally {
    console.log(2);
  }
}

console.log(test1()); // 1 'throw' 2 'from_catch'

function test2() {
  try {
    console.log(1);
    return 'from_try';
  } catch (e) {
    // TODO
  } finally {
    console.log(2);
    return 'from_finally';
  }
}

console.log(test2()); // 1 2 'from_finally' 

这一机制的基础是Javascript语句执行的完成状态,就是Completion Record,它表示一个语句执行完之后的结果,有三个字段:

  • [[type]]:表示完成的类型,有break continue return thrownormal 几种类型;
  • [[value]]:表示语句的返回值,如果语句没有,则是empty;
  • [[target]]:表示语句的目标,通常是一个JavaScript标签

JS引擎在遇到Completion Record为normal的时候,就会继续执行下一条语句,如果不为normal,则会打断语句块后续语句的执行。假如我们在语句块中插入了一条return 语句,产生了一个非normal记录,那么整个语句块会成为非normal。这个结构就保证了非normal的完成类型可以穿透复杂的语句嵌套结构,产生控制效果

{
  var i = 1; // normal, empty, empty
  return i; // return, 1, empty
  i ++; 
  console.log(i);
} // return, 1, empty

那么在控制型语句中,ifswitchwhile/fortrybreakcontinuereturnthrow两两组和产生如下效果:
image

因为finally中的内容必须保证执行,所以try/catch执行完毕,即使得到的结果是非normal型的完成记录,也必须要执行finally
而当finally执行也得到了非normal记录,则会使finally中的记录作为整个try结构的结果。

JavaScript如何实现异步编程,可以详细描述EventLoop机制

image

EventLoop实现过程:

  1. 所有同步任务都在主线程上执行,形成一个执行栈
  2. 主线程之外,有一个任务队列(Task Queue),只要异步任务有了运行结果,就在任务队列中放置一个事件
  3. 一旦执行栈中的所有同步任务执行完毕,系统就会读取任务队列,那些对应的异步任务就结束等待状态,进入执行栈,开始执行
  4. 这个过程不断循环,所以就是事件循环

任务执行优先级:同步任务>微任务>宏任务

宏任务和微任务分别有哪些

宏任务

setTimeout、setInterval、Promise中的executor

微任务

Promise.then

使用Promise实现串行

参考:https://www.manman.io/2019/03/21/promise_series/

Node与浏览器EventLoop的差异

  • Node中新增了一个微任务process.nextTick和一个宏任务setImmediate
  • 在微任务中,process.nextTick的执行优先级比Promise.then
  • Node中的EventLoop分为6个阶段,在每个阶段的循环中,都会先清空当前循环内的主任务队列,然后清空NextTick Queue,再清空Microtask Queue。由此可以看出,浏览器端,microtask在事件循环的macrotask执行完之后执行,而Node端,microtask在事件循环的各个阶段之间执行
    image

如何在保证页面运行流畅的情况下处理海量数据

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant