• js的运行机制


    一直只是知道,js是单线程,栈放基本类型的变量和一些对象的引用,堆放复杂类型的变量(对象),但是,究竟js是怎么样利用单线程的机制实现同步,异步?怎么样出栈入栈的?一直糊里糊涂。今天好好补一下。

    首先来说单线程:

    众所周知,js的核心特点就是单线程,那为什么不选择效率高的多线程呢,这要从最初定义它的用途说起。js 是浏览器脚本语言,它主要用来用户交互和操作DOM,这决定了它只能是单线程。因为,如果是多线程,那比如同时多个线程在操作一个DOM元素,那究竟该取哪个?如果再加锁之类的操作,那就太复杂了,所以,js选择了单线程。

    那就有人要问了,那单线程是不是就意味着js始终是一个任务执行完毕再执行下一个?那怎么做到异步呢?这就是接下来要说的js运行机制了。

    Event  Loop(事件循环):

    先盗用一张图((引自Philip Roberts的演讲《Help, I'm stuck in an event-loop》))

    请按照如下顺序理解:

    1.js在运行时会有一个主线程(当前执行的任务,放在stack中)和一个任务队列(queue);

    2.主线程里放着所有的同步任务,每个任务排队执行,只有上一个执行完毕,才能执行下一个任务;主线程的执行任务形成一个执行栈(后进先出),执行栈在执行的过程中(包括交互触发),调用webapi产生异步任务;

    3.任务队列里放着所有的异步任务,当某个异步任务有了运行结果后,就会在任务队列中放置一个事件;

    4.当主线程中的执行栈为空时,意味着所有同步任务已执行完成,此时,系统就会去任务队列中查看有哪些事件在等待,该事件对应的任务就会进入执行栈执行;

    5.当该执行栈再执行完后,就又会去任务队列查看;

    6.4与5不断循环;

    以上就是event loop;

    此时,估计会有疑问,那遇到耗时长的操作运算,就一直等着?

    当然,我们是要想办法的,或者把它拆分执行,或者搞成异步等。比如:HTML5提出了Web Worker,它会在当前JavaScript的执行主线程中利用Worker类新开辟一个额外的线程来加载和运行特定的JavaScript文件,这个新的线程和JavaScript的主线程之间并不会互相影响和阻塞执行,而且在Web Worker中提供了这个新线程和JavaScript主线程之间数据交换的接口:postMessage和onMessage事件。但在HTML5 Web Worker中是不能操作DOM的,任何需要操作DOM的任务都需要委托给JavaScript主线程来执行,所以虽然引入HTML5 Web Worker,但仍然没有改线JavaScript单线程的本质。

  • 相关阅读:
    【BZOJ-3712】Fiolki LCA + 倍增 (idea题)
    【BZOJ-1941】Hide and Seek KD-Tree
    【BZOJ-2400】Spoj839Optimal Marks 最小割 + DFS
    【BZOJ-3709】Bohater 贪心
    【BZOJ-2342】双倍回文 Manacher + 并查集
    【BZOJ-3790】神奇项链 Manacher + 树状数组(奇葩) + DP
    【BZOJ-4568】幸运数字 树链剖分 + 线性基合并
    【BZOJ-4520】K远点对 KD-Tree + 堆
    【BZOJ-4127】Abs 树链剖分 + 线段树 (有趣的姿势)
    【BZOJ-2648&2716】SJY摆棋子&天使玩偶 KD Tree
  • 原文地址:https://www.cnblogs.com/lichunyan/p/8284650.html
Copyright © 2020-2023  润新知