IndexedDB 和 多线程 Web Worker
一、indexedDB:
参考:https://www.cnblogs.com/zry2510/p/6297000.html 或 http://www.ruanyifeng.com/blog/2018/07/indexeddb.html【推荐】
1、主要概念:
- 数据库: IDBDatabase 对象
- 每个域名(严格的说,是协议 + 域名 + 端口)都可以新建任意多个数据库。
- IndexedDB 数据库有版本的概念。同一个时刻,只能有一个版本的数据库存在。如果要修改数据库结构(新增或删除表、索引或者主键),只能通过升级数据库版本完成。
- 对象仓库: IDBObjectStore 对象,可以理解为表对象,新增数据都是向对象仓库写入数据记录。
- 每个数据库包含若干个对象仓库(object store)。它类似于关系型数据库的表格。
- 数据记录:
- 对象仓库保存的是数据记录。每条记录类似于关系型数据库的行,但是只有主键和数据体两部分。主键用来建立默认的索引,必须是不同的,否则会报错。主键可以是数据记录里面的一个属性,也可以指定为一个递增的整数编号。
- 索引:
- 为了加速数据的检索,可以在对象仓库里面,为不同的属性建立索引。
- 事务:
- 数据记录的读写和删改,都要通过事务完成。事务对象提供
error
、abort
和complete
三个事件,用来监听操作结果。
- 数据记录的读写和删改,都要通过事务完成。事务对象提供
2、操作流程:
1、打开数据库: 使用 indexedDB.open() 方法。
var request = window.indexedDB.open(databaseName, version);
- 这个方法接受两个参数,第一个参数是字符串,表示数据库的名字。如果指定的数据库不存在,就会新建数据库。第二个参数是整数,表示数据库的版本。如果省略,打开已有数据库时,默认为当前版本;新建数据库时,默认为
1
。
2、新建数据库:与打开数据库是同一个操作
request.onupgradeneeded = function(event) { db = event.target.result; // db是全局 声明的一个变量,之后很多地方都是通过这个 对象去操作数据库的 var objectStore = db.createObjectStore('person', { keyPath: 'id' }); // 创建字段 objectStore.createIndex('name', 'name', { unique: false }); objectStore.createIndex('email', 'email', { unique: true }); }
- 新建数据库与打开数据库是同一个操作。如果指定的数据库不存在,就会新建。
- 新建与打开 不同之处在于,新建的操作主要在
upgradeneeded
事件的监听函数里面完成,因为这时版本从无到有,所以会触发这个事件。 - 打开数据库(已存在,注意不是新建)并不会触发upgradeneeded事件,因为版本没有改变。
3、新增数据:新增数据指的是向对象仓库写入数据记录。这需要通过事务完成。
function add() { var request = db.transaction(['person'], 'readwrite') // 这里的db就是我们的全局 IDBDatabase 对象 .objectStore('person') .add({ id: 1, name: '张三', age: 24, email: 'zhangsan@example.com' }); request.onsuccess = function (event) { console.log('数据写入成功'); }; request.onerror = function (event) { console.log('数据写入失败'); } } add();
- 说明:上面代码中,写入数据需要新建一个事务。新建时必须指定表格名称和操作模式("只读"或"读写")。新建事务以后,通过
IDBTransaction.objectStore(name)
方法,拿到 IDBObjectStore 对象,再通过表格对象的add()
方法,向表格写入一条记录。
写入操作是一个异步操作,通过监听连接对象的success
事件和error
事件,了解是否写入成功。
4、读取数据:读取数据也是通过事务完成。
function read() { var transaction = db.transaction(['person']); var objectStore = transaction.objectStore('person'); var request = objectStore.get(1); request.onerror = function(event) { console.log('事务失败'); }; request.onsuccess = function( event) { if (request.result) { console.log('Name: ' + request.result.name); console.log('Age: ' + request.result.age); console.log('Email: ' + request.result.email); } else { console.log('未获得数据记录'); } }; } read();
上面代码中,objectStore.get()
方法用于读取数据,参数是主键的值。
5、遍历数据
6、更新数据:
7、删除数据:
8、使用索引:
索引的意义在于,可以让你搜索任意字段,也就是说从任意字段拿到数据记录。如果不建立索引,默认只能搜索主键(即从主键取值)。
二、多线程 Web Worker:
参考:https://www.jianshu.com/p/5606c919e4dd 或 http://www.ruanyifeng.com/blog/2018/07/web-worker.html
js创建一个子 线程,子线程 执行完程序(一般都是复杂的计算,放在子线程中),返回一个结果给主线程。
var worker = new Worker('work.js');
1、主线程:
a、Worker()
构造函数的参数是一个脚本文件,该文件就是 Worker 线程所要执行的任务。由于 Worker 不能读取本地文件,所以这个脚本必须来自网络。
b、主线程调用worker.postMessage()
方法,向 Worker 发消息。
c、主线程通过worker.onmessage
指定监听函数,接收子线程发回来的消息。
d、主进程 关闭 Worker 线程:
worker.terminate();
2、Worker 线程(子线程):
a、子线程监听 message 事件:
self.addEventListener('message', function (e) { self.postMessage('You said: ' + e.data); }, false);
b、子线程向主线程发送消息 self.postMessage()。
c、子进程内 关闭自身 worker 线程:
self.close();
三、