算法
字典
class Dictionary {
private items = {};
private length = 0;
set(key:string, value:any):boolean{
if(!this.has(key)){
this.items[key] = value;
this.length++;
return true;
}
return false;
}
remove(key:string):boolean{
if(this.has(key)){
delete this.items[key];
this.length--;
return true;
}
return false;
}
has(key:string):boolean{
if(this.items.hasOwnProperty(key)){
return true;
}
return false
}
get(key:string):any{
return this.items[key];
}
clear(){
this.items = {};
this.length = 0;
}
size(){
return this.length;
}
keys():string[]{
return Object.keys(this.items);
}
values():any[]{
return this.keys().map(key => {
return this.items[key]
});
}
}
var dictionary = new Dictionary();
dictionary.set('aaa', 111);
console.log(dictionary.values());
dictionary.set('bbb', 222);
console.log(dictionary.values());
dictionary.set('ccc', 333);
console.log(dictionary.values());
console.log(dictionary.has('aaa'));
console.log(dictionary.get('aaa'));
console.log(dictionary.size());
console.log(dictionary.keys());
dictionary.remove('aaa');
console.log(dictionary.values());
dictionary.remove('ccc');
console.log(dictionary.values());
散列表
class HashTable{
private items:{} = {};
private length:number = 0;
private loseloseHashCode(key:string):number{
var hash = 0;
for(var i=0; i<key.length; i++){
hash += key.charCodeAt(i);
}
return hash % 37;
}
put(key:string, value:any){
var pos = this.loseloseHashCode(key);
this.items[pos] = value;
}
remove(key:string){
var pos = this.loseloseHashCode(key);
delete this.items[pos];
}
get(key:string){
var pos = this.loseloseHashCode(key);
return this.items[pos];
}
}
由于 key 经过 hash 算法之后可能产生重复,这种现象称之为冲突,面对这个问题一般有两种解决方案,一种是分离链接,一种是线性探测。
分离链接
采用链表的方式存储,比如 ae、ea 通过 hash 算法,当计算得到 hash 值之后,在存储这个 hash key 对应的数据时采用链表的方式去存储。下面是大致伪代码的实现
put(key, value){
var pos = this.loseloseHashCode(key);
if(this.items[pos] === undefined){
this.items[pos] = new LinkList();
}
this.items[pos].append(key + '-' + value)
}
get(key){
var pos = this.loseloseHashCode(key);
if(this.items[pos] !== undefined){
return this.item[pos].find(key + '-' + value);
}
return false;
}
线性探测
当前的 hash key 已经被占用时,对当前的 hash key 进行自增,直到找到空的 key 时,将这个值存起来。下面是大致伪代码的实现
put(key, value){
var pos = this.loseloseHashCode(key);
if(this.items[pos] === undefined){
this.items[pos] = key + '-' + value;
}else{
var index = ++ pos;
while(this.items[index]){
index++;
}
this.items[index] = key + '-' + value;
}
}
get(key){
var pos = this.loseloseHashCode(key);
if(this.items[pos] !== undefined){
while(this.items[pos].replace(/\-.*/g, '') === key){
pos++;
}
return this.items[pos]
}
return false;
}
Ajax 和 Comet
XMLHttpRequest 对象
用于发送请求的对象,更早一些的版本会有 ActiveXObject(),现代浏览器都支持 XMLHttpRequest 对象,更新的浏览器支持的 fetch API。(监控错误日志,想要获取到错误的网络请求行为可以通过重写 fetch API 和 XMLHttpRequest 对象获取)
// 获取 XML 对象
var xhr = new XMLHttpRequest();
// 对请求的状态进行监听
xhr.onreadystatuschange = function(){
// 0:未初始化,尚未调用 open 方法
// 1:启动,已经调用 open 方法,并未调用 send 方法
// 2:发送,已经调用 send 方法,但尚未接收到响应
// 3:接收,已经接收到部分响应数据,数据接收中
// 4:完成,已经接收到全部响应数据
if(xhr.readystate == 4){
if(xhr.status === 200){
// 请求结果
xhr.responseText;
}else{
// 请求出错
}
}
}
// 设置超时时间
xhr.timeout = 10000;
// 设置超时的回调函数
xhr.ontimeout = function(){}
// 准备发送请求的参数
xhr.open('method', 'url', 是否异步发送请求);
// 发送请求
xhr.send(data);
// 请求提前结束
xhr.abort();
send方法中的data,只有在post的方法中才会进行传递,如果content-type:application/json,数据需要用json的数据格式来表示。如果content-type:x-www-form-urlencoded,数据则需要用表单的格式,new FormData()通过表单的数据格式进行发送。
xhr 进度事件
- loadstart:在接受到响应数据的第一个字节时触发
- progress:在接收响应期间持续不断地触发
- error:在请求发生错误时错发
- abort:在因为调用 abort 方法而终止连接时触发
- load:在接收到完整的响应数据时触发
- loadend:在通信完成或者触发 error,abort 或 load 事件后触发
xhr.onprogress = function(event){
if(event.lengthComputable){
console.log(`已接收到 ${event.position},一共请求大小 ${event.totalSize} bytes`)
}
}
跨域 http://karynsong.github.io/2015-08/21/
comet
指的是让信息近乎实时的推送到页面。实现方式大致有以下几种:
- 短轮询:通过 setInterval 这样的方式不断的发出请求,来保持和服务器同步,延迟时间就是请求间隔时间,无用的请求会比较多
- 长轮询:服务器接收到请求后,将请求 hold 住,等到有数据时返回,没有延迟时间,但是服务器会建立非常多连接,性能会是一种考验。
- SSE,通过 EventSource 对象发起与服务器建的连接,服务器返回的 MIME 类型必须是 text/event-stream,基于事件流的处理。
- websocket:是 HTTP 之上的连接方式,但是不是属于 HTTP 协议,通过 new WebSocket 得到实例。只能发送字符串,当然也可以发送 json。
websocket
var socket = new WebSocket('ws://xxx.xxx.xxx');
socket.onopen = function(){}
socket.onerror = function(){}
socket.onclose = function(){}
socket.onmessage = function(event){
var data = event.data;
}