摘要:單線程與瀏覽器多線程是單線程的因為運行在瀏覽器中,是單線程的,每個一個線程。若以多線程的方式操作這些,則可能出現操作的沖突。零延遲零延遲并不是意味著回調函數立刻執行。異步編程的中方法包括回調函數事件監聽采用事件驅動模式。
JavaScript單線程與瀏覽器多線程
Javascript是單線程的:因為JS運行在瀏覽器中,是單線程的,每個window一個JS線程。作為瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操作DOM。若以多線程的方式操作這些DOM,則可能出現操作的沖突。假設有兩個線程同時操作一個DOM元素,線程1要求瀏覽器刪除DOM,而線程2卻要求修改DOM樣式,這時瀏覽器就無法決定采用哪個線程的操作。
瀏覽器不是單線程的,引擎可能存在如下線程:
javascript引擎線程
界面渲染線程
瀏覽器事件觸發線程
Http請求線程等
Event Loop事件循環機制:
主線程從"任務隊列"中讀取事件,這個過程是循環不斷的,所以整個的這種運行機制又稱為Event Loop(事件循環)。主線程運行的時候,產生堆(heap)和棧(stack),棧中的代碼調用各種外部API,它們在"任務隊列"中加入各種事件(click,load,done)。只要棧中的代碼執行完畢,主線程就會去讀取"任務隊列",依次執行那些事件所對應的回調函數。
執行棧:所有同步任務都在主線程上執行,形成一個執行棧;
任務隊列:主線程之外,還存在一個"任務隊列"(task queue)。只要異步任務有了運行結果,就在"任務隊列"之中放置一個事件,當棧為空時,就會從任務隊列中取出一個任務并執行。
定時器:
定時器包括setTimeout與setInterval兩個方法。它們的第二個參數是指定其回調函數推遲每隔多少毫秒數后執行。
零延遲 setTimeout(func, 0):零延遲并不是意味著回調函數立刻執行。它取決于主線程當前是否空閑與“任務隊列”里其前面正在等待的任務。當計時器時間規定的時候,回調函數會被添加到“任務隊列”中,等到執行棧的任務執行完畢,就會來執行這里的任務。所以,有的時候即使計時器已經到0了,也會不立即執行計時器中的回調任務。
Ajax異步請求:
在發起ajax請求的時候,瀏覽器會開一個線程去執行這一步驟,發請求這一步是屬于執行棧中的同步任務,在請求發完之后就會執行棧中的下一個任務,而等到請求有了結果,就會把結果放入“任務隊列”中,等待執行;
JavaScript是單線程的,所謂“單線程”,就是同一時間只能執行一個任務。如果有多個任務,就必須排隊,直到前一個任務完成。這種模式的好處就是實現比較簡單,尤其在瀏覽器環境中,可以避免很多不必要的麻煩。壞處就是如果一個任務耗時很長,那么該任務后面的任務就必須一直等待,導致整個頁面都卡住無法繼續往下執行。
為了解決這個問題,JavaScript將任務的執行模式分為兩類,一個是同步模式,另一個是異步模式。
"同步模式"就是上一段的模式,后一個任務等待前一個任務結束,然后再執行,程序的執行順序與任務的排列順序是一致的、同步的;"異步模式"則完全不同,每一個任務有一個或多個回調函數(callback),前一個任務結束后,不是執行后一個任務,而是執行回調函數,后一個任務則是不等前一個任務結束就執行,所以程序的執行順序與任務的排列順序是不一致的、異步的。
JS異步編程的4中方法包括:
回調函數:
f1(); f2(); function f1(callback){ setTimeout(function(){ callback(); }) } f1(f2);
事件監聽:采用事件驅動模式。任務的執行不取決于代碼的順序,而取決于某個事件是否發生。
//jQuery f1.on("done", f2); function f1(){ setTimeout(function () { //do something f1.trigger("done");//執行完成后,立即觸發done事件,從而開始執行f2。 }, 1000); }
發布/訂閱:又稱觀察者模式
jQuery.subscribe("done", f2);//訂閱"done"這個信號 function f1(){ setTimeout(function () { //do something jQuery.publish("done");//f1()執行完之后,發出"done"這個信號,f2開始執行 }, 1000); } jQuery.unsubscribe("done", f2);//取消訂閱
Promises:ES6原生提供了Promise對象。所謂Promise對象,就是代表了未來某個將要發生的事件(通常是一個異步操作)。它的好處在于,有了Promise對象,就可以將異步操作以同步操作的流程表達出來,避免了層層嵌套的回調函數。此外,Promise對象還提供了一整套完整的接口,使得可以更加容易地控制異步操作。
var promise = new Promise(function(resolve, reject) { if (/* 異步操作成功 */){ resolve(value); } else { reject(error); } }); promise.then(function(value) { // success }, function(value) { // failure });ES6模塊管理
ECMAScript 6基于export和import,定義了模塊的導出和導入規范,在語言標準層面實現了模塊機制。該標準的目標是創建一種能夠兼容CommoneJS和AMD兩標準的規范,即可以像CommoneJS一樣語法簡潔、使用單一的接口且支持循環依賴,又可以像AMD支持異步加載和可配置的模塊加載。
大致來說,當 JS 引擎運行一個模塊的時候,它的行為大致可歸納為以下四步:
解析:引擎實現會閱讀模塊的源碼,并且檢查是否有語法錯誤。
加載:引擎實現會(遞歸地)加載所有被引入的模塊。
鏈接:引擎實現會為每個新加載的模塊創建一個作用域,并且將模塊中的聲明綁定填入其中,包括從其他模塊中引入的。
JS加載動態加載常用的4種方法:
document.write:document.write("");
動態改變已有script的src屬性:js.src = "package.js";
動態創建script元素:
var script = document.createElement("script"); script.src = "XXX"; script.type = "XXX"; document.head.appendChild(script);
用XMLHTTP取得要腳本的內容,再創建 Script 對象。
項目中加載JS的方法:
在頁面底部寫一個自調用函數,加載入口JS,然后入口中的方法執行,加載需要的其他JS。
在VM平臺上,可以選擇將幾個模塊分組打包到一個入口文件中,然后在這個入口文件中,將每個組動態生成一個script標簽,插入head中。
異步加載:
瀏覽器在渲染一個頁面的時候,遇到一個標簽就會去下載對應的js文件,如果采用同步加載JS的方式,會造成頁面阻塞,直到JS加載完成再繼續渲染,所以有了異步加載JS的形式。
常見的異步加載JS方式,將js代碼包裹在匿名函數中并立即執行,動態生成標簽去拉取js,可以實現多個js文件并行下載,只有在解析執行的時候會阻塞渲染。另外,可以使用script標簽的async和defer屬性。
延遲加載:
延遲加載就是一開始并不加載這些暫時不用的js,而是在需要的時候或稍后再通過js 的控制來異步加載。
也就是將 js 切分成許多模塊,頁面初始化時只加載需要立即執行的 js ,然后其它 js 的加載延遲到第一次需要用到的時候再加載。
特別是頁面有大量不同的模塊組成,很多可能暫時不用或根本就沒用到。
script的兩階段加載與延遲執行
JS的加載其實是由兩階段組成:下載內容(download bytes)和執行(parse and execute)。
瀏覽器在下載完 js 的內容后就會立即對其解析和執行,不管是同步加載還是異步加載。
前面說的異步加載,解決的只是下載階段的問題,但代碼在下載后會立即執行。
而瀏覽器在解析執行 JS 階段是阻塞任何操作的,這時的瀏覽器處于無響應狀態。
我們都知道通過網絡下載 script 需要明顯的時間,但容易忽略了第二階段,解析和執行也是需要時間的。script的解析和執行所花的時間比我們想象的要多,尤其是script 很多很大的時候。有些是需要立刻執行,而有些則不需要(比如只是在展示某個界面或執行某個操作時才需要)。
這些script 可以延遲執行,先異步下載緩存起來,但不立即執行,而是在第一次需要的時候執行一次。
利用特殊的技巧可以做到下載與執行的分離。比如將 JS 的內容作為object對象加載緩存起來,所以就不會立即執行了,然后在第一次需要的時候再執行。
多表查詢:
定義:根據特定的連接條件從不同的表中獲取所需的數據;
語法:SELECT table1.column, table2.column FROM table1, table2 WHERE table1.column1 = table2.column2;
注意:where不要省了,省略where即為笛卡爾集,而且where條件要有效,兩張表間有一個相同的字段,才好進行有效的多表查詢;
簡化:為了簡化SQL書寫,可為表名定義別名,格式:from 表名別名,如:from emp e,dept d;
優化:建議使用表的別名及表前綴,使用表別名可以簡化查詢,而使用表前綴則可以提高查詢性能;
連接類型:從數據顯示方式來講有:內連接和外連接。
內連接:只返回滿足連接條件的數據。
例:select empno,ename,sal,dname,loc from emp,dept where emp.deptno=dept.deptno;
等值連接:在連接條件中使用等于號(=)運算符比較被連接列的列值,其查詢結果中列出被連接表中的所有列,包括其中的重復列。
不等值連接:在連接條件使用除等于運算符以外的其它比較運算符比較被連接的列的列值。這些運算符包括>、>=、<=、<、!>、!<和<>。
自然連接:在連接條件中使用等于(=)運算符比較被連接列的列值,但它使用選擇列表指出查詢結果集合中所包括的列,并刪除連接表中的重復列。
外連接:除了返回滿足連接條的行以外,還返回左(右)表中,不滿足條件的行,稱為左(右)連接;
左外連接:是以左表為基準,將左表沒有的對應項顯示,右表的列為NULL
select * from book as a left join stu as b on a.sutid = b.stuid
右外連接:是以右表為基準,將a.stuid = b.stuid的數據進行連接,然以將右表沒有的對應項顯示,左表的列為NULL
select * from book as a right join stu as b on a.sutid = b.stuid
全連接:完整外部聯接返回左表和右表中的所有行。當某行在另一個表中沒有匹配行時,則另一個表的選擇列表列包含空值。如果表之間有匹配行,則整個結果集行包含基表的數據值。
select * from book as a full outer join stu as b on a.sutid = b.stuid
CI框架常用的數據庫操作:
常規查詢:$this->db->query("YOUR QUERY HERE");
查詢綁定:查詢綁定可以簡化你的查詢語法,它通過系統自動的為你將各個查詢組裝在一起。 參考下面的例子:
$sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?"; $this->db->query($sql, array(3, "live", "Rick"));
$this->db->count_all():該方法用于獲取數據表的總行數,第一個參數為表名;
查詢構造器類:odeIgniter 提供了查詢構造器類,查詢構造器允許你使用較少的代碼來在數據庫中 獲取、新增或更新數據。有時只需要一兩行代碼就能完成數據庫操作。CodeIgniter 并不需要為每個數據表提供一個類,而是使用了一種更簡單的接口。
查詢:
$query = $this->db->get("mytable"); // Produces: SELECT * FROM mytable $query = $this->db->get("mytable", 10, 20); // Executes: SELECT * FROM mytable LIMIT 20, 10 // (in MySQL. Other databases have slightly different syntax)
$this->db->select():該方法用于編寫查詢語句中的 SELECT 子句:
$this->db->select("title, content, date"); $query = $this->db->get("mytable"); // Executes: SELECT title, content, date FROM mytable
$this->db->from():該方法用于編寫查詢語句中的 FROM 子句:
$this->db->select("title, content, date"); $this->db->from("mytable"); $query = $this->db->get(); // Produces: SELECT title, content, date FROM mytable
$this->db->join():該方法用于編寫查詢語句中的 JOIN 子句:
$this->db->select("*"); $this->db->from("blogs"); $this->db->join("comments", "comments.id = blogs.id"); $query = $this->db->get(); // Produces: // SELECT * FROM blogs JOIN comments ON comments.id = blogs.id //你可以傳入第三個參數指定連接的類型,有這樣幾種選擇:left,right,outer,inner,left outer 和 right outer 。 $this->db->join("comments", "comments.id = blogs.id", "left"); // Produces: LEFT JOIN comments ON comments.id = blogs.id
$this->db->where():該方法提供了4中方式讓你編寫查詢語句中的 WHERE 子句(所有的數據將會自動轉義,生成安全的查詢語句。):
1.簡單的 key/value 方式: $this->db->where("name", $name); // Produces: WHERE name = "Joe" 注意自動為你加上了等號。 如果你多次調用該方法,那么多個 WHERE 條件將會使用 AND 連接起來: $this->db->where("name", $name); $this->db->where("title", $title); $this->db->where("status", $status); // WHERE name = "Joe" AND title = "boss" AND status = "active" 2.自定義 key/value 方式: 為了控制比較,你可以在第一個參數中包含一個比較運算符: $this->db->where("name !=", $name); $this->db->where("id <", $id); // Produces: WHERE name != "Joe" AND id < 45 3.關聯數組方式: $array = array("name" => $name, "title" => $title, "status" => $status); $this->db->where($array); // Produces: WHERE name = "Joe" AND title = "boss" AND status = "active" 你也可以在這個方法里包含你自己的比較運算符: $array = array("name !=" => $name, "id <" => $id, "date >" => $date); $this->db->where($array); 4.自定義字符串: 你可以完全手工編寫 WHERE 子句: $where = "name="Joe" AND status="boss" OR status="active""; $this->db->where($where); $this->db->where() 方法有一個可選的第三個參數,如果設置為 FALSE,CodeIgniter 將不保護你的表名和字段名。 $this->db->where("MATCH (field) AGAINST ("value")", NULL, FALSE);
$this->db->like():該方法用于生成 LIKE 子句,在進行搜索時非常有用。
簡單 key/value 方式: $this->db->like("title", "match"); // Produces: WHERE `title` LIKE "%match%" ESCAPE "!" 如果你多次調用該方法,那么多個 WHERE 條件將會使用 AND 連接起來: $this->db->like("title", "match"); $this->db->like("body", "match"); // WHERE `title` LIKE "%match%" ESCAPE "!" AND `body` LIKE "%match% ESCAPE "!" 可以傳入第三個可選的參數來控制 LIKE 通配符(%)的位置,可用選項有:"before","after" 和 "both" (默認為 "both")。 $this->db->like("title", "match", "before"); // Produces: WHERE `title` LIKE "%match" ESCAPE "!" $this->db->like("title", "match", "after"); // Produces: WHERE `title` LIKE "match%" ESCAPE "!" $this->db->like("title", "match", "both"); // Produces: WHERE `title` LIKE "%match%" ESCAPE "!" 關聯數組方式: $array = array("title" => $match, "page1" => $match, "page2" => $match); $this->db->like($array); // WHERE `title` LIKE "%match%" ESCAPE "!" AND `page1` LIKE "%match%" ESCAPE "!" AND `page2` LIKE "%match%" ESCAPE "!"
$this->db->group_by():$this->db->group_by("title"); // Produces: GROUP BY title;
$this->db->order_by():$this->db->order_by("title", "DESC");
$this->db->limit():$this->db->limit(10); // Produces: LIMIT 10
$this->db->count_all_results():該方法用于獲取特定查詢返回結果的數量,也可以使用查詢構造器的這些方法: where(),or_where(),like(),or_like() 等等。
$this->db->delete():$this->db->delete("mytable", array("id" => $id)); // Produces: // DELETE FROM mytable // WHERE id = $id
為什么chrome瀏覽器的速度很快Chrome 把瀏覽器上做的每件事都拆成獨立的進程,每個tab都是一個獨立的進程,并利用進程間通訊來完成它們之間的同步,windows系統下可以通過任務管理器看到許多chrome 標簽頁的進程。
在還沒點擊 URL 之前,Chrome 已經在幫用戶加載了
參考文章:
JavaScript的加載和執行性能優化
Javascript 異步加載詳解
ES6 的模塊系統
seaJs學習筆記之seaJs的異步加載和加載多個js文件
Promise對象
Javascript異步編程的4種方法
JavaScript 運行機制詳解:再談Event Loop
JavaScript:徹底理解同步、異步和事件循環(Event Loop)
JavaScript單線程和瀏覽器事件循環簡述
Javascript是單線程的深入分析
查詢輔助函數
SQL的幾種連接:內連接、左聯接、右連接、全連接、交叉連接
SQL基礎-->多表查詢
CHROME進程間通信
瀏覽器是如何工作的
瀏覽器是怎樣工作的:渲染引擎,HTML解析
等......
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79865.html
摘要:簡介項目命名為就是一個服務器單純開發一個服務器的想法,變成構建網絡應用的一個基本框架發展為一個強制不共享任何資源的單線程,單進程系統。單線程弱點無法利用多核錯誤會引起整個應用退出,應用的健壯性大量計算占用導致無法繼續調用異步。 NodeJs簡介 Ryan Dahl項目命名為:web.js 就是一個Web服務器.單純開發一個Web服務器的想法,變成構建網絡應用的一個基本框架.Node發展...
摘要:線程機制與事件機制一進程與線程進程程序的一次執行,它占有一片獨有的內存空間。事件響應模塊負責事件的管理。當事件發生時管理模塊會將回調函數及其數據添加到回調列隊中。但是子線程完全受主線程控制,且不得操作。向另一個線程發送消息。 JavaScript線程機制與事件機制 一、進程與線程 進程(process) 程序的一次執行,它占有一片獨有的內存空間。 可以通過windows任務管理器查...
摘要:深入淺出一直想致力于寫一篇關于廣義講解系統的文章,苦于時間有限,資源有限。事件驅動機制是通過內部單線程高效率地維護事件循環隊列來實現的,沒有多線程的資源占用和上下文的切換。 深入淺出Node.js 一直想致力于寫一篇關于廣義講解Node.js系統的文章,苦于時間有限,資源有限。這篇文章是在結合自己的學習心得以及與行業大佬共同探討下爭對于熟練掌握JS語言后的廣義Node.js.至于為什么...
閱讀 472·2023-04-25 17:26
閱讀 1495·2021-08-05 09:58
閱讀 1959·2019-08-30 13:17
閱讀 943·2019-08-28 17:52
閱讀 1061·2019-08-26 18:27
閱讀 1413·2019-08-26 14:05
閱讀 3608·2019-08-26 14:05
閱讀 1586·2019-08-26 10:45