瀏覽器不是單線程的,引擎可能存在以下線程:javascript
事件循環機制:
主線程從"任務隊列"中讀取事件,這個過程是循環不斷的,因此整個的這種運行機制又稱爲Event Loop(事件循環)。主線程運行的時候,產生堆(heap)和棧(stack),棧中的代碼調用各類外部API,它們在"任務隊列"中加入各類事件(click,load,done)。只要棧中的代碼執行完畢,主線程就會去讀取"任務隊列",依次執行那些事件所對應的回調函數。php
定時器:
定時器包括setTimeout與setInterval兩個方法。它們的第二個參數是指定其回調函數推遲每隔多少毫秒數後執行。
零延遲 setTimeout(func, 0):零延遲並非意味着回調函數馬上執行。它取決於主線程當前是否空閒與「任務隊列」裏其前面正在等待的任務。當計時器時間規定的時候,回調函數會被添加到「任務隊列」中,等到執行棧的任務執行完畢,就會來執行這裏的任務。因此,有的時候即便計時器已經到0了,也會不當即執行計時器中的回調任務。html
Ajax異步請求:
在發起ajax請求的時候,瀏覽器會開一個線程去執行這一步驟,發請求這一步是屬於執行棧中的同步任務,在請求發完以後就會執行棧中的下一個任務,而等到請求有告終果,就會把結果放入「任務隊列」中,等待執行;java
JavaScript是單線程的,所謂「單線程」,就是同一時間只能執行一個任務。若是有多個任務,就必須排隊,直到前一個任務完成。這種模式的好處就是實現比較簡單,尤爲在瀏覽器環境中,能夠避免不少沒必要要的麻煩。壞處就是若是一個任務耗時很長,那麼該任務後面的任務就必須一直等待,致使整個頁面都卡住沒法繼續往下執行。git
爲了解決這個問題,JavaScript將任務的執行模式分爲兩類,一個是同步模式,另外一個是異步模式。github
"同步模式"就是上一段的模式,後一個任務等待前一個任務結束,而後再執行,程序的執行順序與任務的排列順序是一致的、同步的;"異步模式"則徹底不一樣,每個任務有一個或多個回調函數(callback),前一個任務結束後,不是執行後一個任務,而是執行回調函數,後一個任務則是不等前一個任務結束就執行,因此程序的執行順序與任務的排列順序是不一致的、異步的。ajax
JS異步編程的4中方法包括:sql
回調函數:chrome
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 });
ECMAScript 6基於export和import,定義了模塊的導出和導入規範,在語言標準層面實現了模塊機制。該標準的目標是建立一種可以兼容CommoneJS和AMD兩標準的規範,便可以像CommoneJS同樣語法簡潔、使用單一的接口且支持循環依賴,又能夠像AMD支持異步加載和可配置的模塊加載。
大體來講,當 JS 引擎運行一個模塊的時候,它的行爲大體可概括爲如下四步:
動態加載經常使用的4種方法:
document.write("<script src='package.js'><\/script>");
js.src = "package.js";
動態建立script元素:
var script = document.createElement("script"); script.src = "XXX"; script.type = "XXX"; document.head.appendChild(script);
項目中加載JS的方法:
在頁面底部寫一個自調用函數,加載入口JS,而後入口中的方法執行,加載須要的其餘JS。
<script> (function(G,D){var el=D.createElement('script'),d="XXX'; el.src=((G._moduleConfig&&G._moduleConfig.domain)?G._moduleConfig.domain:d)+"XXX?t=XXX"; D.getElementsByTagName('head')[0].appendChild(el); })(this,document); </script>
在VM平臺上,能夠選擇將幾個模塊分組打包到一個入口文件中,而後在這個入口文件中,將每一個組動態生成一個script標籤,插入head中。
異步加載:
瀏覽器在渲染一個頁面的時候,遇到一個<script>
標籤就會去下載對應的js文件,若是採用同步加載JS的方式,會形成頁面阻塞,直到JS加載完成再繼續渲染,因此有了異步加載JS的形式。
常見的異步加載JS方式,將js代碼包裹在匿名函數中並當即執行,動態生成<script>
標籤去拉取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;
鏈接類型:從數據顯示方式來說有:內鏈接和外鏈接。
內鏈接:只返回知足鏈接條件的數據。
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
參考文章:
JavaScript的加載和執行性能優化
Javascript 異步加載詳解
ES6 的模塊系統
seaJs學習筆記之seaJs的異步加載和加載多個js文件
Promise對象
Javascript異步編程的4種方法
JavaScript 運行機制詳解:再談Event Loop
JavaScript:完全理解同步、異步和事件循環(Event Loop)
JavaScript單線程和瀏覽器事件循環簡述
Javascript是單線程的深刻分析
查詢輔助函數
SQL的幾種鏈接:內鏈接、左聯接、右鏈接、全鏈接、交叉鏈接
SQL基礎-->多表查詢
CHROME進程間通訊
瀏覽器是如何工做的
瀏覽器是怎樣工做的:渲染引擎,HTML解析等......