原文链接: js 运行时
上一篇: js fork
下一篇: iview 中事件处理函数中的$event参数获取原生事件发出的信息
堆heap
栈stack
队列queue
帧frame
帧
一个帧是一个连续的工作单元, 当一个js函数被调用时, 运行时环境就会在栈中创建一个帧, 帧里面保存了特殊函数的参数和局部变量,当函数返回时, 帧就从栈中弹出. 如果出现递归死循环, 栈会被完全填满, 出现栈溢出错误
栈
栈包含了一个信息在执行时的所有步骤, 栈的数据结构为一个后进先出的对象集合, 因此, 当一个帧被加入到一个栈中时, 他总是被添加在最上面
由于栈是一个后进先出的集合, 所以事件循环会从上至下处理栈中的帧, 单帧所依赖的其他帧, 将会被添加在此帧的上面, 以保证它从栈中可以获取到所依赖的信息
队列
队列中包含一个 待执行的信息列表, 每一个信息都与一个函数相联系, 当栈为空时, 队列中的一条信息就会被取出并且被处理, 处理的过程为调用该信息所关联的函数, 然后将此帧添加到栈的顶部. 当栈再次为空时, 本次信息处理过程视为结束
堆
堆是一个内存存储空间, 它不关注内部存储的内容的保存顺序, 堆中保存了所有正在被使用的变量和对象, 同时也保存了一些当前作用域已经不再会被用到,但还没有被垃圾回收的帧
事件循环
事件循环内的信息是线性执行的, 这意味着它收到一个信息后, 在处理完毕之前不会再处理 其他任何信息
每当一个函数被调用, 队列中就被加入一个新的信息, 如果栈是空的, 那么函数就会立刻执行(即表示该函数的帧被添加到了栈中)
当所有的帧都被加入栈中后, 栈便开始从上至下的一个个执行并清除这些帧, 最后栈会被清空, 然后下一个信息将会被处理.
web worker 可以在不同的线程内处理后台任务, 他们各自拥有自己的队列 堆和栈
事件循环的好处是, 执行顺序是非常容易预测且追踪的, 另一个好处是在事件循环内可以进行非阻塞IO操作, 这意味着当一个应用在等待IO的执行结果时, 他还可以处理其他事情, 比如处理用户输入
事件循环的缺点是, 当一个信息需要大量的时间来处理时, 应用会变得无响应, 一个好的做法是保持每个信息处理尽量简短 , 可能的话, 将一个信息函数分割为多个小函数