Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 亚洲视频三区,国产在线观看91精品一区,亚洲国产精品自产在线播放

          整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          JavaScript精通到深入

          幾天教大家從入門到精通,當(dāng)然僅靠那一篇文章是不足以帶領(lǐng)大家精通JavaScript的,今天給大家?guī)淼诙v!

          BOM和DOM簡介

          BOM,Browser Object Model ,瀏覽器對象模型。

          BOM主要提供了訪問和操作瀏覽器各組件的方式。

          瀏覽器組件:

          window(瀏覽器窗口)

          location(地址欄)

          history(瀏覽歷史)

          screen(顯示器屏幕)

          navigator(瀏覽器軟件)

          document(網(wǎng)頁)

          DOM,Document Object Model,文檔對象模型。

          DOM主要提供了訪問和操作HTML標(biāo)記的方式。

          HTML標(biāo)記:

          圖片標(biāo)記

          表格標(biāo)記

          表單標(biāo)記

          body、html標(biāo)記

          ……

          BOM和DOM不是JS的內(nèi)容。它們是W3C制定的規(guī)范。但是,BOM和DOM在瀏覽器中以對象的形式得以實現(xiàn)。

          換句話說:BOM和DOM都是由一組對象構(gòu)成。

          W3C是制作互聯(lián)網(wǎng)標(biāo)準(zhǔn)的一個國際化的組織,如:XHTML、CSS、JavaScript、AJAX等。

          BOM對象結(jié)構(gòu)圖

          各對象之間是有層級關(guān)系的,那么各對象之間如何訪問呢?

          window.document.write(“OK”)

          window.document.body.bgColor = “#FF0000”;

          window對象是所有其它對象的最頂層對象,因此,可以省略。

          document.write(“OK”);

          document.body.bgColor = “#FF0000”;

          window.alert(“OK”); ——> alert(“OK”);

          window.prompt(“請輸入一個分?jǐn)?shù)”); ——> prompt(“請輸入一個分?jǐn)?shù)”);

          Window對象屬性

          name:指瀏覽器窗口的名字或框架的名字。這個名字是給<a>標(biāo)記的target屬性來用的。

          設(shè)置窗口的名字:window.name = “newWin”

          獲取窗口的名字:document.write(name);

          top:代表最頂層窗口。如:window.top

          parent:代表父級窗口,主要用于框架。

          self:代表當(dāng)前窗口,主要用于框架中。

          innerWidth:指瀏覽器窗口的內(nèi)寬(不含菜單欄、工具欄、地址欄、狀態(tài)欄),該屬性Firefox支持。

          在IE下,使用 document.documentElement.clientWidth 來代替 window.innerWidth

          innerHeight:指瀏覽器窗品的內(nèi)高(不含菜單欄、工具欄、地址欄、狀態(tài)欄),該屬性Firefox支持。

          在IE下,使用 document.documentElement.clientHeight 來代替 window.innerHeight

          document.documentElement就是<html>標(biāo)記對象

          document.body 就是 <body>標(biāo)記對象

          window對象方法

          alert():彈出一個警告對話框。

          prompt():彈出一個輸入對話框。

          confirm():彈出一個確認對話框。如果單擊“確定按鈕”返回true,如果單擊“取消”返回false。

          close():關(guān)閉窗口

          print():打印窗口

          open()方法

          功能:打開一個新的瀏覽器窗口。

          語法:var winObj = window.open([url][,name][,options]);

          說明:參數(shù)可有可無。如果沒有指定參數(shù),則打開一個選項卡式的窗口(大小是最大大化)。

          參數(shù):

          url:準(zhǔn)備在新窗口中顯示哪個文件。url可以為空字符串,表示顯示一個空的頁面。

          name:新窗口的名字,該名字給<a>標(biāo)記的target屬性來用。

          options:窗口的規(guī)格。

          width:新窗口的寬度

          height:新窗口的高度

          left:新窗口距離屏幕左邊的距離

          top:新窗口距離屏幕上邊的距離

          menubar:是否顯示菜單欄,取值:yes、no

          toolbar:是否顯示工具欄。

          location:是否顯示地址欄。

          status:是否顯示狀態(tài)欄。

          scrollbars:是否顯示滾動條,不能省略s字母。

          返回值:返回一個window對象的變量,可以通過該名稱跟蹤該窗口。winObj具備window對象的所有屬性和方法。

          onload事件:當(dāng)網(wǎng)頁加載完成,指<body>標(biāo)記的所有內(nèi)容全部加載完成,才觸發(fā)該事件(條件)。通過onload事件屬性,去調(diào)用JS的函數(shù)。onload屬性只有<body>標(biāo)記才有。

          onclick事件:當(dāng)單擊時,去調(diào)用JS代碼。所有HTML標(biāo)記都具有該事件屬性。

          延時器方法——setTimeout()

          setTimeout()

          功能:設(shè)置一個延時器,換句話說:時間一到,就執(zhí)行JS代碼一次

          語法:var timer = window.setTimeout(code,millisec)

          參數(shù):

          code:是任何合法的JS代碼,一般情況下是JS函數(shù)。該函數(shù)要放在引號中。

          舉例:window.setTimeout(“close()” , 2000)

          舉例:window.setTimeout(init, 2000); //傳函數(shù)地址,因此不需要加括號。如果加括號,是將函數(shù)的執(zhí)行結(jié)果傳到方法中。

          millisec:毫秒值。1秒=1000毫秒

          返回值:返回一個延時器的id變量,這個id變量給clearTimeout()用來清除。

          clearTimeout()

          功能:清除延時器id變量

          語法:window.clearTimeout(timer)

          參數(shù):timer就是由setTimeout()設(shè)置的延時器的id變量。

          實例:計數(shù)器

          定時器方法

          setInterval()

          功能:設(shè)置一個定時器。定時器,重復(fù)不斷的執(zhí)行JS代碼(周期性)。

          語法: var timer = window.setInterval(code , millisec)

          參數(shù):

          code:是任何合法的JS代碼,一般情況下是JS函數(shù)。該函數(shù)要放在引號中。

          舉例:window.setInterval(“init()” , 2000)

          舉例:window.setInterval(init, 2000); //傳函數(shù)地址,因此不需要加括號。如果加括號,是將函數(shù)的執(zhí)行結(jié)果傳到方法中。

          millisec:毫秒值。1秒=1000毫秒

          返回值:返回一個定時器的id變量,這個id變量給clearInterval()用來清除。

          clearInterval()

          功能:清除定時器id變量

          語法:window.clearInterval(timer)

          參數(shù):timer就是由setInterval()設(shè)置的定時器的id變量。

          實例:圖片自動切換

          screen屏幕對象

          Width:屏幕的寬度,只讀屬性。

          Height:屏幕的高度,只讀屬性。

          availWidth:屏幕的有效寬度,不含任務(wù)欄。只讀屬性。

          availHeight:屏幕的有效高度,不含任務(wù)欄。只讀屬性。

          navigator對象

          appName:瀏覽器軟件名稱,主要用來判斷客戶使用的是什么核心的瀏覽器。

          如果是IE瀏覽器的話,返回值為:Microsoft Internet Explorer

          如果是Firefox瀏覽器的話,返回值為:Netscape

          appVersion:瀏覽器軟件的核心版本號。

          systemLanguage:系統(tǒng)語言

          userLanguage:用戶語言

          platform:平臺

          Location地址欄對象

          href:獲取地址欄中完整的地址。可以實現(xiàn)JS的網(wǎng)頁跳轉(zhuǎn)。location.href = “http://www.sina.com.cn”;

          host:主機名

          hostname:主機名

          pathname:文件路徑及文件名

          search:查詢字符串。

          protocol:協(xié)議,如:http://、ftp://

          hash:錨點名稱。如:#top

          reload([true]):刷新網(wǎng)頁。true參數(shù)表示強制刷新

          注意:所有的屬性,重新賦值后,網(wǎng)頁將自動刷新。

          <meta http-equiv = “refresh” content = “5;url=http://www.sina.com.cn” />

          history對象

          length:歷史記錄的個數(shù)

          go(n):同時可以實現(xiàn)“前進”和“后退。”

          i.history.go(0) 刷新網(wǎng)頁

          ii.history.go(-1) 后退

          iii.history.go(1) 前進一步

          iv.history.go(3) 前進三步

          forward():相當(dāng)于瀏覽器的“前進”按鈕

          back():相當(dāng)于瀏覽器的“后退”按鈕

          下面我們來講DOM

          DOM的官方定義

          DOM , Document Object Model ,文檔對象模型。我們可以把網(wǎng)頁中的所有“東西”看成是“對象”。

          DOM是W3C制定的網(wǎng)頁標(biāo)準(zhǔn)或規(guī)則,而這個標(biāo)準(zhǔn),在瀏覽器中,以“對象”的形式得以實現(xiàn)。

          DOM的官方定義:DOM可以使腳本動態(tài)的訪問或操作,網(wǎng)頁的內(nèi)容、網(wǎng)頁外觀、網(wǎng)頁結(jié)構(gòu)。

          DOM的分類

          核心DOM:提供了同時操作HTML文檔和XML文檔的公共的屬性和方法

          HTML DOM:針對HTML文檔提供的專用的屬性方法。

          XML DOM:針對XML文檔提供的專用的屬性和方法。(就業(yè)班講)

          CSS DOM:提供了操作CSS的屬性和方法。

          Event DOM:事件對象模型。如:onclick、 onload等。

          HTML節(jié)點樹

          節(jié)點關(guān)系

          根節(jié)點,一個HTML文檔只有一個根,它就是HTML節(jié)點。

          子節(jié)點:某一個節(jié)點的下級節(jié)點。

          父節(jié)點:某一個節(jié)點的上級節(jié)點。

          兄弟節(jié)點:兩個子節(jié)點同屬于一個父節(jié)點。

          DOM中節(jié)點類型

          document文檔節(jié)點,代表整個網(wǎng)頁,不代表任何HTML標(biāo)記。但它是html節(jié)點的父節(jié)點。

          element元素節(jié)點,指任何HTML標(biāo)記。每一個HTML標(biāo)記就稱一個“元素節(jié)點”。它可以有文本節(jié)點和屬性節(jié)點。

          attribute屬性節(jié)點。指HTML標(biāo)記的屬性。

          text節(jié)點。是節(jié)點樹的最底節(jié)點。

          核心DOM中的公共的屬性和方法

          提示:核心DOM中查找節(jié)點(標(biāo)記),都是從根節(jié)點開始的(html節(jié)點)。

          1、節(jié)點訪問

          nodeName:節(jié)點名稱。

          nodeValue:節(jié)點的值。只有文本節(jié)點才有值,元素節(jié)點沒有值。nodeValue的值只能是“純文本”,不能含有任何的HTML標(biāo)記或CSS屬性。

          firstChild:第1個子節(jié)點。

          lastChild:最后1個子節(jié)點。

          childNodes:子節(jié)點列表,是一個數(shù)組。

          parentNode:父節(jié)點。

          查找<html>標(biāo)記的方法

          document.firstChild

          document.documentElement

          查找<body>標(biāo)記的方法

          document.firstChild.lastChild

          document.body

          為什么,document.body.firstChild找不到<table>節(jié)點?

          核心DOM的屬性和方法,主要是針對HTML4.0開發(fā)的。

          在Firefox下,會把空格或換行,當(dāng)成文本節(jié)點。

          HTML4.0是有沒有DTD類型定義的。

          2、對節(jié)點的屬性操作

          setAttribute(name,value):給某個節(jié)點添加一個屬性。

          getAttribute(name):獲取某個節(jié)點屬性的值。

          removeAttribute(name):刪除某個節(jié)點的屬性。

          3、節(jié)點的創(chuàng)建

          document.createElement(tagName):創(chuàng)建一個指定的HTML標(biāo)記,一個節(jié)點

          tagName:是指不帶尖括號的HTML標(biāo)記名稱。

          舉例:var imgObj = document.createElement(“img”)

          parentNode.appendChild(childNode):將創(chuàng)建的節(jié)點,追加到某個父節(jié)點下。

          parentNode代表父節(jié)點,父節(jié)點必須存在。

          childNode代表子節(jié)點。

          舉例:document.body.appendChild(imgObj)

          parentNode.removeChild(childNode):刪除某個父節(jié)點下的子節(jié)點。

          parentNode代表父節(jié)點。

          childNode代表要刪除的子節(jié)點。

          舉例:document.body.removeChild(imgObj)

          綜合實例:隨機顯示小星星

          <script type="text/javascript">

          //實例:隨機顯示小星星

          /*

          (1)網(wǎng)頁背景色為黑色

          (2)創(chuàng)建圖片節(jié)點,追加到<body>父節(jié)點

          (3)圖片隨機大小

          (4)圖片隨機定位坐標(biāo)(x,y)

          (5)定時器

          (6)網(wǎng)頁加載完成,開始星星

          (7)星星顯示的范圍,跟窗口的寬高一樣。(0,window.innerWidth)

          (8)點擊星星,星星消失

          */

          //網(wǎng)頁加載完成

          window.onload = function(){

          //更改網(wǎng)頁背景色

          document.body.bgColor = "#000";

          //定時器:1秒鐘,顯示一個星星

          window.setInterval("star()",1000);

          }

          //動畫主函數(shù)

          function star()

          {

          //創(chuàng)建圖片節(jié)點

          var imgObj = document.createElement("img");

          //添加src屬性

          imgObj.setAttribute("src","images/xingxing.gif");

          //添加width屬性。getRandom()隨機數(shù)函數(shù)

          var width = getRandom(15,85);

          imgObj.setAttribute("width",width);

          //添加style屬性(行內(nèi)樣式)。

          var x = getRandom(0,window.innerWidth);

          var y = getRandom(0,window.innerHeight);

          imgObj.setAttribute("style","position:absolute;left:"+x+"px;top:"+y+"px;");

          //添加onclick事件屬性

          //this代表當(dāng)前對象,this是一個對象。

          //this是系統(tǒng)關(guān)鍵字。this只能在函數(shù)內(nèi)使用。

          imgObj.setAttribute("onclick","removeImg(this)");

          //將圖片節(jié)點,掛載到<body>父節(jié)點下

          document.body.appendChild(imgObj);

          }

          //函數(shù):求隨機數(shù)函數(shù)

          function getRandom(min,max)

          {

          //隨機數(shù)

          var random = Math.random()*(max-min)+min;

          //向下取整

          random = Math.floor(random);

          //返回結(jié)果

          return random;

          }

          //函數(shù):刪除節(jié)點

          function removeImg(obj)

          {

          document.body.removeChild(obj);

          }

          </script>

          </head>

          <body>

          </body>

          HTML DOM簡介和新特性

          1、簡介

          核心DOM中,提供的屬性和方法,已經(jīng)可以操作網(wǎng)頁了。為什么還要有HTMLDOM呢?

          如果在核心DOM中,網(wǎng)頁中節(jié)點層級很深時,訪問這個節(jié)點時將十分麻煩。

          那么,HTMLDOM中就提供了通過id直接找節(jié)點的方法,而不用再HTML根節(jié)點開始。

          2HTMLDOM的新特性

          每一個HTML標(biāo)記,都對應(yīng)一個元素對象。如:<img>對應(yīng)一個圖片對象

          每一個HTML標(biāo)記的屬性,與對應(yīng)的元素對象的屬性,一一對應(yīng)。

          HTML DOM訪問HTML元素的方法(最常用)

          1getElementById()

          功能:查找網(wǎng)頁中指定id的元素對象。

          語法:var obj = document.getElementById(id)

          參數(shù):id是指網(wǎng)頁中標(biāo)記的id屬性的值。

          返回值:返回一個元素對象。

          舉例:var imgObj = document.getElementById(“img01”)

          2getElementsByTagName(tagName)

          功能:查找指定的HTML標(biāo)記,返回一個數(shù)組。

          語法:var arrObj = parentNode.getElementsByTagName(tagName)

          參數(shù):tagName是要查找的標(biāo)記名稱,不帶尖括號。

          返回值:返回一個數(shù)組。如果只有一個節(jié)點,也返回一個數(shù)組。

          舉例:var arrObj = ulObj.getElementsByTagName(“l(fā)i”)

          元素對象的屬性

          tagName:標(biāo)簽名稱,與核心DOM中nodeName一樣。

          className:CSS類的樣式。

          id:同HTML標(biāo)記id屬性一樣。

          title:同HTML標(biāo)記的title屬性一樣。

          style:同HTML標(biāo)記的style屬性一樣。

          innerHTML:包含HTML標(biāo)記中的所有的內(nèi)容,包括HTML標(biāo)記等。

          以上元素對象屬性的應(yīng)用,詳細看文件。

          offsetWidth:元素對象的可見寬度,不帶px單位。

          offsetHeight:元素對象的可見高度,不帶px單位。

          scrollWidth:元素對象的總寬度,包括滾動條中的內(nèi)容,不帶px單位。

          scrollHeight:元素對象的總高度,包括滾動條中的內(nèi)容,不帶px單位。

          scrollTop:指內(nèi)容向上滾動上去了多少距離(有滾動條時才有效),默認值為0

          scrollLeft:指內(nèi)容向左滾動過去了多少距離(有滾動條時才有效)。

          onscroll:當(dāng)拖動滾動條時,調(diào)用JS函數(shù)。

          綜合案例:書訊快遞

          oochow Instruments 發(fā)布 Delay Lab 是一款適用于 Korg drumlogue 鼓機的全新免費用戶延遲插件。據(jù)開發(fā)者稱,drumlogue 已具備延時功能,但無法產(chǎn)生明顯的合唱或鑲邊效果。因此,Boochow Instruments 決定開發(fā)一款專為合唱和鑲邊效果而設(shè)計的插件。



          Boochow Instruments 是一款立體聲延時器,提供正、負和交叉反饋選項。此外,它還配備了一個 LFO,用于調(diào)節(jié)延遲時間。此外,它還內(nèi)置了濾波器,可對延遲特性進行微調(diào)。

          開發(fā)者稱,它可用于制作各種基于延遲的效果,包括節(jié)奏延遲、鑲邊和合唱效果。




          Boochow Instruments Delay Lab 現(xiàn)提供免費下載。它只能在 Korg drumlogue 上運行,采用第二代 SDK 邏輯引擎。

          Boochow Instruments 官網(wǎng):
          https://synthanatomy.com/2023/10/boochow-instruments-delay-lab-free-delay-plugin-for-korg-drumlogue.html

          youtobe視頻鏈接:
          https://youtu.be/tXW_degI5GM


          Boochow Instruments 發(fā)布 Delay Lab 適用于Korg drumlogue 免費鼓機延遲插件

          https://www.audioapp.cn/bbs/thread-221990-1-1.html

          (出處: 音頻應(yīng)用)

          前言

          作為一個前端工程師,瀏覽器是我們密不可分的朋友,想要深耕前端,就必須和瀏覽器“交心”。

          為什么你覺得偶爾看瀏覽器的工作原理,但總是忘呢?,因為你沒有形成一個完整的知識網(wǎng)絡(luò),你的記憶是碎片化的。正如人的神經(jīng)網(wǎng)絡(luò),只有當(dāng)你的記憶相互依賴,相互鏈接,才能形成長期穩(wěn)定的記憶。

          所以本文我將用一條知識線將瀏覽器工作原理的知識串聯(lián)起來,因為本文的目的是為了幫助大家建立瀏覽器基礎(chǔ)的思維樹,所以很多細節(jié)點不做過多闡述,先有了樹,后面你在上面伸展枝葉就會發(fā)現(xiàn)清晰明了很多。歡迎點贊支持或評論指正。

          一、了解進程、線程

          進程:計算機正在運行的一個程序的實例。每個進程都有自己的內(nèi)存空間、系統(tǒng)資源(如文件描述符、I/O 等),以及一個或多個線程(執(zhí)行指令的基本單位);

          線程:線程是進程中的執(zhí)行單元,是操作系統(tǒng)調(diào)度的最小單位。在一個進程中可以有多個線程,它們共享進程的資源,但擁有各自的執(zhí)行流。線程是進程的一部分,同一個進程中的多個線程可以并發(fā)執(zhí)行,共享進程的地址空間和系統(tǒng)資源。

          通俗的說,比如瀏覽器是一座工廠,進程就是工廠里的不同車間,線程是車間里的流水線,它是是工廠中的實際運作單位。

          你需要了解:

          • 進程具有獨立性,所有進程互相隔離,獨立運行。一個進程崩潰不會影響其他進程。進程與進程之間的通信,是通過進程間通信(Inter-Process Communication,簡稱IPC)來進行數(shù)據(jù)交換和協(xié)作的。
          • 一個進程包含多個線程,每個線程并行執(zhí)行不同的任務(wù)。其中一個線程崩潰了,那么整個進程也就崩潰了。線程之間可以相互通信。

          并行和并發(fā)

          關(guān)于并行和并發(fā)的概念一定要清晰,因為很多問題的根源或者性能優(yōu)化方案都是依靠并行或并發(fā)的。

          并發(fā)是指多個任務(wù)在同一時間段內(nèi)交替執(zhí)行,從外部看似乎是同時執(zhí)行的

          并行是指多個任務(wù)在同一時刻同時執(zhí)行

          關(guān)于進程通信(IPC)

          進程間通信方式有以下七種:

          1. 管道(Pipe): 管道是一種半雙工的通信方式,它在父進程和子進程之間創(chuàng)建一個共享的文件描述符,通過文件描述符進行通信。管道可以分為匿名管道和命名管道。
          2. 消息隊列(Message Queue): 消息隊列是一種進程間通信的機制,進程通過發(fā)送消息到隊列,其他進程可以從隊列中接收消息。消息隊列提供了一種異步的通信方式。
          3. 共享內(nèi)存(Shared Memory): 共享內(nèi)存允許多個進程訪問同一塊物理內(nèi)存區(qū)域,進程可以直接讀寫共享內(nèi)存中的數(shù)據(jù)。共享內(nèi)存是一種高效的 IPC 方式,但需要額外的同步機制來確保數(shù)據(jù)的一致性。
          4. 信號量(Semaphore): 信號量是一種用于進程同步的機制,它可以用來控制對共享資源的訪問。信號量可以用于解決臨界區(qū)問題,確保多個進程按照一定順序訪問共享資源。
          5. 套接字(Socket): 套接字是一種網(wǎng)絡(luò)編程中常用的通信方式,它可以在同一臺主機上的不同進程間進行通信,也可以在網(wǎng)絡(luò)上的不同主機上的進程間進行通信。
          6. 文件映射(File Mapping): 文件映射允許多個進程共享同一文件的內(nèi)存映射區(qū)域,可以通過對這個內(nèi)存區(qū)域的讀寫來進行進程間通信。
          7. 信號(Signal): 信號是一種軟件中斷,用于通知進程發(fā)生了某個事件。進程可以通過注冊信號處理函數(shù)來捕獲和處理信號。

          根據(jù)交換信息量的多少和效率的高低,分為低級通信和高級通信。以上共享內(nèi)存、管道、消息隊列、套接字屬于高級通信。

          這里簡單說下Chrome的 IPC 通信機制。它的渲染器進程通信由 Mojo 實現(xiàn)(以前是使用Chromium IPC),Mojo 是源于 Chrome 的 IPC 跨平臺框架,它誕生于 chromium ,用來實現(xiàn) chromium 進程內(nèi)/進程間的通信。目前,它也被用于 ChromeOS。

          想了解 Mojo的,可以看下 Mojo 設(shè)計者寫的文檔:Mojo介紹

          線程安全

          上面我提到了,線程會共享進程的地址空間和系統(tǒng)資源。所以這些擁有共享數(shù)據(jù)的多條線程處理并發(fā)式任務(wù)時,由于多個線程操作同一資源,操作時間并未錯開,而使得內(nèi)存中的操作重復(fù),從而數(shù)據(jù)錯亂,造成線程安全問題。具體線程安全的原因可以總結(jié)為以下5點:

          1. 搶占式執(zhí)行:多線程的調(diào)度是隨機的,萬惡之源;
          2. 多線程修改同一個變量:這個很好理解,就是多個線程同時修改一個變量,就會出現(xiàn)問題,這里就不舉例了;
          3. 操作是原子的:簡單來說就是每個線程的指令都是獨立的,所以修改同一變量時才會出問題,對此問題,我們可以把相同操作的所有指令封裝到一起;
          4. 指令重排序:編譯器可能會改變兩個操作的先后順序,處理器也可能不會按照目標(biāo)代碼的順序執(zhí)行。內(nèi)核這樣的操作其實是對內(nèi)存訪問有序操作的一種優(yōu)化,可以在不影響單線程程序正確的情況下提升程序的性能,但是同時就會可能影響代碼執(zhí)行的正確性,導(dǎo)致線程安全問題;
          5. 內(nèi)存可見性問題:當(dāng)多個線程訪問同一個變量時,一個線程修改了這個變量的值,其他線程應(yīng)該能夠立即看得到修改后的值,但是在多線程環(huán)境下,一個線程對共享變量的操作對其他線程是不可見的,所以無法立即同步數(shù)據(jù)。

          總結(jié)來講,就是線程并發(fā)或者內(nèi)核優(yōu)化機制導(dǎo)致的線程安全問題。那怎么解決線程安全問題呢?一般有以下幾種思路:

          1. 鎖機制、互斥量、信號量: 這些都是同步控制的機制,通過對關(guān)鍵區(qū)域的加鎖,確保在同一時刻只有一個線程能夠訪問共享資源。加鎖是非常常見的解決線程安全的手段;
          2. 線程安全的數(shù)據(jù)結(jié)構(gòu): 使用線程安全的數(shù)據(jù)結(jié)構(gòu)可以減少對共享數(shù)據(jù)的直接訪問,從而減小同步的壓力。
          3. Web Workers: 在一些需要并行計算的場景下,使用 Web Workers 可以將任務(wù)分發(fā)到獨立的線程中執(zhí)行,減少對主線程的競爭。
          4. 事件驅(qū)動: 使用事件驅(qū)動的編程模型,通過發(fā)布和訂閱事件來進行通信,可以降低對共享狀態(tài)的依賴。
          5. Atomic操作: 使用原子操作,確保某些操作在執(zhí)行時是不可中斷的,避免了在多線程環(huán)境下的競爭問題。

          二、瀏覽器有哪些進程?

          現(xiàn)在的瀏覽器基本都是采用多進程架構(gòu)設(shè)計,即一個標(biāo)簽頁(也就是一個網(wǎng)頁)會啟用多個進程,一般至少有如下四個進程:

          • 瀏覽器進程:整個瀏覽器的主進程,負責(zé)協(xié)調(diào)、控制其他進程;
          • 渲染進程(也可以叫內(nèi)核進程):負責(zé)渲染頁面內(nèi)容的進程;
          • 網(wǎng)絡(luò)進程:負責(zé)處理網(wǎng)絡(luò)請求,每個標(biāo)簽頁都共享同一個網(wǎng)絡(luò)進程,以減少資源占用。
          • GPU進程:負責(zé)處理瀏覽器中與圖形相關(guān)的任務(wù),,例如加速頁面繪制、處理 CSS 動畫、執(zhí)行 WebGL 操作等。GPU 進程與渲染進程分離,以提高性能。

          除此以外,還可能開辟插件進程,如果頁面使用了插件(例如 Flash、Java 等),則會有對應(yīng)的插件進程。

          渲染進程(也叫內(nèi)核進程,因為瀏覽器內(nèi)核、js引擎就是在渲染進程中工作的)和網(wǎng)絡(luò)進程是我們前端程序員最需要關(guān)注的兩個進程,下面我們就分別說說這兩個進程究竟干了些什么?

          三、渲染進程有哪些線程?

          五大類線程

          渲染進程共有以下5類線程:

          注意是5類線程,不是5個線程,例如GUI渲染線程就有渲染主線程、布局線程、合成器線程、柵格線程等;

          1. GUI渲染線程:負責(zé)渲染網(wǎng)頁,具體見下一章,當(dāng)頁面觸發(fā)重繪、回流時該線程也會執(zhí)行;

          注意:GUI渲染線程和JS引擎線程是互斥的(因為GUI 渲染線程和 JavaScript 引擎線程都需要訪問和操作 DOM,所以做了線程安全的處理),當(dāng)JS引擎執(zhí)行時GUI線程會被掛起,GUI更新會被保存在一個隊列中等到JS引擎空閑時立即被執(zhí)行。這也就是為什么js文件會阻塞頁面加載,一般最好放在html底部引入的原因。

          1. JS引擎線程:該線程是使用js引擎處理Javascript腳本程序,解析Javascript腳本,運行代碼;
          2. 事件觸發(fā)線程:負責(zé)處理用戶輸入和觸發(fā)相應(yīng)的事件(例如,點擊按鈕時,事件觸發(fā)線程會負責(zé)處理這個點擊事件)。它管理一個事件隊列,當(dāng)對應(yīng)的事件被觸發(fā)時,事件觸發(fā)線程會把該事件添加到事件隊列的隊尾,等待JS引擎的處理;
          3. 定時器觸發(fā)線程:負責(zé)處理通過 setTimeout 和 setInterval 等方法設(shè)置的定時器,觸發(fā)相應(yīng)的回調(diào)函數(shù)。
          4. 異步HTTP請求線程:XMLHttpRequest連接后,瀏覽器會新開一個線程請求,檢測到狀態(tài)變更時,如果設(shè)置有回調(diào)函數(shù),異步線程就產(chǎn)生狀態(tài)變更事件,將回調(diào)函數(shù)放入事件隊列中,等待JS引擎空閑后執(zhí)行;

          為什么事件觸發(fā)、定時器觸發(fā)、異步異步HTTP請求都會有各自的線程處理呢?因為JS引擎是單線程的,這些異步任務(wù)會阻塞js的執(zhí)行。所以要單獨開啟幾個線程和主線程并行執(zhí)行。
          這些處理異步操作的線程會把所有異步任務(wù)推到一個任務(wù)隊列里,等待 JS 引擎空閑時,再把他們添加到可執(zhí)行棧中,開始執(zhí)行(這里就又延伸到 Event Loop 的機制了)

          渲染進程中的異步HTTP請求線程和網(wǎng)絡(luò)進程有何區(qū)別?

          看到這里有同學(xué)就要問了,渲染進程中的異步HTTP請求線程負責(zé)處理異步 HTTP 請求,那瀏覽器的另一個進程-網(wǎng)絡(luò)進程是干嘛呢?兩個有什么區(qū)別?

          渲染進程中的異步 HTTP 請求線程是專門用來處理 JavaScript 層面的異步網(wǎng)絡(luò)請求的,例如使用XMLHttpRequest 對象或 Fetch API。而網(wǎng)絡(luò)進程就比較全面了,它負責(zé)處理所有的網(wǎng)絡(luò)操作,包括頁面導(dǎo)航、處理主頁面的請求、子頁面的請求、資源加載等。

          另外他們兩個是協(xié)同工作的,例如 JS 發(fā)起的異步網(wǎng)絡(luò)請求,要經(jīng)歷:DNS 解析:-> 建立連接 -> 發(fā)送請求 -> 接收響應(yīng)

          當(dāng)HTTP 異步請求線程處理 JS 代碼發(fā)起的請求時,DNS 解析和建立連接通常在網(wǎng)絡(luò)進程中執(zhí)行,HTTP 異步請求線程則負責(zé)發(fā)送請求和接收響應(yīng)。

          四、事件循環(huán)機制Event Loop

          上面我們說了事件循環(huán)機制基于 JS 線程是單線程的。雖然渲染進程有很多線程,但是JavaScript執(zhí)行是在一個單一的線程中進行的。

          以下是事件循環(huán)的過程

          • 主線程的任務(wù)是不斷地執(zhí)行執(zhí)行棧中的代碼。
          • 當(dāng)執(zhí)行棧為空時,會檢查任務(wù)隊列中是否有待執(zhí)行的任務(wù)。
          • 如果有,將任務(wù)隊列中的回調(diào)函數(shù)添加到執(zhí)行棧,繼續(xù)執(zhí)行。

          從上面渲染引擎的幾大線程角度來說,JS事件循環(huán)機制可以這么理解:

          當(dāng) JS 引擎從上至下按順序執(zhí)行代碼時,遇到異步任務(wù),會交由其他幾個負責(zé)異步任務(wù)的線程去執(zhí)行(事件觸發(fā)線程、定時器線程、異步Http請求線程)并將異步回調(diào)推到任務(wù)隊列里。

          想要快速理解事件循環(huán)機制?了解以下這幾點就明白了,不明白你提刀來砍我

          • 任務(wù)隊列有兩組,一個是宏任務(wù)隊列,一個是微任務(wù)隊列,定時器線程會把定時器回調(diào)推到宏任務(wù)隊列,其他異步任務(wù)都會被推到微任務(wù)隊列;
          • 執(zhí)行時是執(zhí)行一個宏任務(wù),然后執(zhí)行這個宏任務(wù)里產(chǎn)生的所有微任務(wù),然后再執(zhí)行一個宏任務(wù),再執(zhí)行這個宏任務(wù)里產(chǎn)生的所有微任務(wù),一直循環(huán)下去;
          • 其實你可以這么理解,把定時器的回調(diào)內(nèi)容不要當(dāng)作異步代碼,只是被延遲執(zhí)行的同步代碼。上一點就可以理解成執(zhí)行完所有同步任務(wù),執(zhí)行所有產(chǎn)生的異步任務(wù),然后再執(zhí)行所有同步任務(wù),再執(zhí)行產(chǎn)生的所有異步任務(wù);
          • 最后超簡單的理解,你可以這么想,忽略宏任務(wù)里的setImmediate(node.js的函數(shù),瀏覽器中不存在)、I/O 操作等,在瀏覽器中,宏任務(wù)其實只需要關(guān)注定時器、延時器。所以可以這么想:JS 從上向下執(zhí)行,同步代碼執(zhí)行完后,執(zhí)行除了定時器以外的所有異步任務(wù),然后執(zhí)行一個定時器,再執(zhí)行所有除了定時器以外的所有異步任務(wù),一直往復(fù)下去...

          五、網(wǎng)絡(luò)進程有哪些線程

          網(wǎng)絡(luò)進程里我們需要知道以下線程:

          • DNS 解析線程(DNS Thread): 負責(zé)進行 DNS 解析,將域名解析為 IP 地址。
          • SSL 線程(SSL Thread): 處理 SSL/TLS 相關(guān)的加密和安全通信。
          • 網(wǎng)絡(luò)請求線程(Network Thread): 負責(zé)處理主要的網(wǎng)絡(luò)請求和響應(yīng),包括接收和發(fā)送數(shù)據(jù)。
          • IPC 線程(Inter-Process Communication Thread): 負責(zé)進程間通信。

          網(wǎng)絡(luò)進程的主要工作包括:

          • 發(fā)起和處理網(wǎng)絡(luò)請求,包括 HTTP 請求、WebSocket 等。
          • 執(zhí)行 DNS 解析,將域名解析為 IP 地址。
          • 建立和管理網(wǎng)絡(luò)連接。
          • 處理安全通信,包括 SSL/TLS 加密。
          • 處理緩存,包括 HTTP 緩存的讀取和寫入。
          • 處理文件的讀取和寫入。
          • 與其他進程(如瀏覽器進程)進行通信。

          六、詳解渲染進程|瀏覽器引擎工作原理

          本章主要講解瀏覽器的兩個引擎:渲染引擎、js引擎的工作原理。包括渲染引擎的渲染過程、js引擎的工作原理、js引擎的垃圾回收機制、內(nèi)存泄漏問題定位等

          書接下回,點個關(guān)注敬請期待(更新后會在此處貼上鏈接)

          七、詳解網(wǎng)絡(luò)進程|Http協(xié)議

          本章主要講解與網(wǎng)絡(luò)進程息息相關(guān)的網(wǎng)絡(luò)通信協(xié)議相關(guān)的知識,例如TCP/IP協(xié)議、TCP建立連接的過程、https加密機制、http首部字段等知識

          書接下回,點個關(guān)注敬請期待(更新后會在此處貼上鏈接)

          八、網(wǎng)頁加載超詳細全流程

          從 URL 輸入到頁面展現(xiàn)到底發(fā)生了什么?這是一個老生常談的問題。我將會從網(wǎng)絡(luò)通信協(xié)議、進程協(xié)作、瀏覽器引擎工作流程等全方位講解這個過程。幫你真正理解網(wǎng)頁的加載過程,而不是浮于表面。

          書接下回,點個關(guān)注敬請期待(更新后會在此處貼上鏈接)

          說在最后

          因為篇幅問題,本文先列出來整體的思維網(wǎng)絡(luò),后面詳細的一些講解單獨抽離,作為系列文章以后更新,感興趣的可以點個關(guān)注,不要錯過~

          先看后贊,養(yǎng)成習(xí)慣
          收藏吃灰,不如學(xué)會
          點個關(guān)注,不要迷路


          作者:前端阿彬
          鏈接:https://juejin.cn/post/7341983885726187559


          主站蜘蛛池模板: 中文字幕一区二区人妻性色| 91成人爽a毛片一区二区| 精品无码综合一区| 国产一区视频在线| 精品国产AV无码一区二区三区 | 无码人妻AⅤ一区二区三区水密桃 无码欧精品亚洲日韩一区夜夜嗨 无码毛片一区二区三区中文字幕 无码毛片一区二区三区视频免费播放 | 精品免费AV一区二区三区| 国产成人一区二区三区在线观看| 在线观看视频一区二区| 色窝窝无码一区二区三区| 亚洲日韩国产一区二区三区| 91精品乱码一区二区三区| 久久亚洲一区二区| 97久久精品午夜一区二区| 国产人妖视频一区二区破除| 亚洲高清日韩精品第一区| 在线精品亚洲一区二区小说| 精品人妻一区二区三区四区在线| 中文字幕亚洲一区| 中文字幕日韩欧美一区二区三区| 精品无码人妻一区二区三区18| 日本一区二区三区在线视频观看免费 | 中文字幕一区在线播放| 精品免费国产一区二区三区| 秋霞无码一区二区| 日韩精品一区二区三区四区| 精品久久国产一区二区三区香蕉| 精品一区二区三区中文| 精品国产一区在线观看| 国产自产对白一区| 日本一区频道在线视频| 亚洲一区在线免费观看| 亚洲视频一区二区三区| 免费无码VA一区二区三区| 久久精品视频一区| 久久国产免费一区| 一区二区三区视频在线观看| 无码少妇一区二区性色AV| 秋霞午夜一区二区| 亚洲国产美国国产综合一区二区| 国产精品视频一区二区三区四|