浏览器不是单线程的,引擎可能存在以下线程: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解析等......