requestAnimationFrame()

每次浏览器重绘之前会调用这个方法!!!

它接收一个参数,就是回调函数;

它可以保证在最佳的间隔时间调用传入的回调函数,以达到让屏幕产生最流畅的动画效果。每次调用这个api它只会调用一次回调函数,并且给回调函数传入间隔的时间(毫秒)。很适合用js做动画。

下面这个方法可以打印出不同浏览器两次重绘的间隔时间(毫秒):

      (function(){
function draw(timestamp){
// 计算两次重绘的时间间隔
var drawStart=(timestamp||Date.now()),
diff=drawStart-startTime;
//使用diff确定下一步的重绘时间
// console.log(diff);//这就是当前浏览器当前重绘的时间间隔(毫秒)
// 把startTime重写为这一次的绘制时间
startTime=drawStart;
// 重绘UI
requestAnimationFrame(draw);
}
var requestAnimationFrame=window.requestAnimationFrame||
window.mozRequestAnimationFrame||
window.webkitRequestAnimationFrame||
window.msRequestAnimationFrame,
startTime=window.mozAnimationStartTime||Date.now();
console.log(startTime);
requestAnimationFrame(draw);
})();

以上代码只兼容IE、chrome、firefox浏览器

Page Vilibility API

用于确认页面是否被隐藏。

document.hidden: 表示页面是否隐藏的布尔值。页面隐藏包含页面在后台标签中或者浏览器最小化。

document.visibilityState:它有以下几种可能的值

visible : 页面内容至少是部分可见。 在实际中,这意味着页面是非最小化窗口的前景选项卡。

hidden : 页面内容对用户不可见。 在实际中,这意味着文档可以是一个后台标签,或是最小化窗口的一部分,或是在操作系统锁屏激活的状态下。

prerender : 页面内容正在被预渲染且对用户是不可见的(被document.hidden当做隐藏). 文档可能初始状态为prerender,但绝不会从其它值转为该值。 注释:浏览器支持是可选的。

unloaded : 页面正在从内存中卸载。 注释:浏览器支持是可选的。

visibilitychange:这是一个document可以监听的事件,当文档从可见变为不可见或者从不可见变为可见时,触发该事件。

Geolocation API:(只有在服务器运行才能生效、协议必须是https)

这个api的实现是navigator.geolocation,这个对象包含3个方法:
getCurrentPosition(成功回调函数,可选的失败回调函数,可选的选项对象):

成功回调函数会接收到一个Position对象参数,给对象有两个属性:coords和timestamp:

coords对象中将包含下列与位置相关的信息:

latitude:以十进制表示的纬度。

longitude:以十进制表示的经度。

accuracy:经、纬度坐标的经度,以米为单位。

有些浏览器还可能会在coords对象中提供如下属性:

altitude:以米为单位的海拔高度,如果没有相关数据则值为null。

altitudeAccuracy:海拔高度的精度,以米为单位,数值越大越不精确。

heading:指南针的方向,0表示正北,值为NAN表示没有检测到数据。

speed:速度,即每秒移动多少米,如果没有相关数据则值为null。

在失败回调函数在被调用的时候也会接收到一个参数,这个参数是一个数组,数组中包含了对象,对象包含两个属性:message和code。其中,message属性中保存着给人看的文本信息,解释为什么会出错。而code保存着一个数值。

第三个参数时一个选项对象:可以设置的选项有三个:

enableHighAccuracy:是一个布尔值,表示必须尽可能使用最精准的位置信息。

timeout:以毫秒数表示的等待位置信息的最长时间。

maximumAge:表示上一次取得的坐标信息的有效时间,以毫秒表示,如果时间到则重新取得新坐标信息。

例子:

      function geolocationSupport(){
if(!navigator.geolocation){
alert("你的浏览器不支持HTML5 Geolocation");
}else{
getCurrentPosition();
}
}
function getCurrentPosition(){
var options={
enableHighAccuracy:true,
timeout:60000,
maximumAge:60000
}
navigator.geolocation.getCurrentPosition(success,error,options)
}
function success(position)
{
var x=position.coords.longitude;
var y=position.coords.latitude;
alert("经度为:"+x+"纬度为:"+y);
}
function error(err)
{
var errorTypes={
1:"用户拒绝定位服务",
2:"获取不到定位信息",
3:"获取定位信息超时"
}
alert(errorTypes[err.code]);
}
window.onload=geolocationSupport();

File API:

当文件输入字段选择了一或多个文件时,文件输入元素的files集合中将包含一组File对象,每个File对象对应着一个文件。每个File对象都有下列只读属性:

name:本地文件系统中的文件名。

size:文件的字节大小。

type:字符串,文件的MIME类型。

lastModifiedDate:字符串,文件上一次被修改的时间。(chrome)

例如:

    <input type="file" id="file_list" multiple="multiple">  

按ctrl键,可以选择多个文件

      var fileList=document.getElementById("file_list");
fileList.onchange=function(event){
var files=event.target.files,
i=0,
len=files.length;
console.log(files);
while(i<len){
console.log(files[i].name+" ("+files[i].type+", "+files[i].size+" bytes");
i++;
}
}

FileReader类型

异步

FileReader类型是用来读取文件的,读取的文件需要是文件输入元素的files集合中的File对象。读取后的数据都将保存在实例的result属性中,它的实例用以下几个方法:

readAsText(读取的文件,可选的指定编码类型):以纯文本形式读取文件。

readAsDataURL(读取的文件):读取文件并将文件以数据URL的形式保存在result属性中。

readAsBinaryString(读取的文件) :读取文件并将以一个字符串保存在result属性中,字符串中的每个字符表示一字节。

readAsArrayBuffer(读取的文件):读取文件并将一个包含文件内容的ArrayBuffer保存在result属性中。

由于读取过程是异步的,因此FileReader也提供了几个事件,这几个事件通过实例监听:

progress:是否又读取了新数据,每50ms左右,就会触发一次。它的事件对象有以下几个属性。

  lengthComputable:表示进度信息是否可用的布尔值。

  loaded:表示已经接收的字节数。

  total:表示根据Content-Length响应头部确定的预期字节数。

error:由于种种原因无法读取文件,就会触发error事件。相关的信息将保存到FileReader的error属性中。这个属性中将保存一个对象,该对象只有一个属性code,即错误码。这个错误码是1表示未找到文件,是2表示安全性错误,是3表示读取中断,是4表示文件不可读。

load:文件成功加载后触发这个事件。

如果项中断读取过程,可以调用abort()方法,这样就会触发abort事件。在触发load、error或abort事件后,会触发另外一个事件loadend。

举例:

      var fileList=document.getElementById("file_list");
fileList.onchange=function(event){
var info="",
output=document.getElementById("file_list"),
progress=document.getElementById("progress"),
files=event.target.files,
type="default",
reader=new FileReader();
if(/image/.test(files[0].type)){
reader.readAsDataURL(files[0]);//若是图片文件,将图片以数据URI的形式保存在result属性中
type="image";
}else{
reader.readAsText(files[0]);//若不是图片文件,将文件以文本的形式保存在result属性中
type="text";
} reader.onerror=function(){//读取失败处理程序
output.innerHTML="Could not read file , error code is"+reader.error.code;
} reader.onprogress=function(event){//读取过程事件处理程序大概50ms执行一次
if(event.lengthComputable){
progress.innerHTML=event.loaded+"/"+event.total;
}
} reader.onload=function(){//成功读取文件的处理程序
var html="";
switch(type){
case "image":
html="<img src="+reader.result+">";
break;
case "text":
html=reader.result;
break;
}
progress.innerHTML=html;
console.log(reader.result);
} }

读取部分内容

File对象还支持一个slice()方法,在firefox中叫mozSlice(),在chrome中叫webkitSlice()。

slice(起始字节,要读取的字节数):这个是File对象的方法,返回一个Blob的实例,Blob是File类型的父类型。通过FileReader也可以从Blob中读取数据。

下面是一个通用的函数:

      function blobSlice(blob,startByte,length){//返回一个Blob实例
if(blob.slice){
return blob.slice(startByte,length);
}else if(blob.webkitSlice){
return blob.webkitSlice(startByte,length);
}else if(blob.mozSlice){
return blob.mozSlice(startByte,length);
}else{
return null;
}
}

Blob类型有一个size属性和一个type属性,而且他也支持slice()方法,以便进一步切割数据。通过FileReader也可以从Blob中读取数据下面这个例子只读取文件的32B内容。

      var fileList=document.getElementById("file_list");

      function blobSlice(blob,startByte,length){
if(blob.slice){
return blob.slice(startByte,length);
}else if(blob.webkitSlice){
return blob.webkitSlice(startByte,length);
}else if(blob.mozSlice){
return blob.mozSlice(startByte,length);
}else{
return null;
}
} fileList.onchange=function(event){
var info="",
output=document.getElementById("file_list"),
progress=document.getElementById("progress"),
files=event.target.files,
reader=new FileReader(),
blob=blobSlice(files[0],0,32);
if(blob){
reader.readAsText(blob); reader.onerror=function(){
progress.innerHTML="Could not read file,error code is"+reader.error.code;
} reader.onload=function(){
progress.innerHTML=reader.result;
}
}else{
console.log("Your browser doesn't support slice().");
} }

对象URL

对象URL也被称为blob URL,指的是引用保存在File或Blob中数据的URL。可以不必用FileReader的readAsDataURL()方法来获取数据的url,而直接可以使用文件。

window.URL.createObjectURL(File或Blob对象):返回一个字符串,指向一块内存的地址。因为这个字符串是URL,所以在DOM中的img元素的src属性也能使用。

window.URL.revokeObjectURL(url):如果不再需要相应的数据,最好释放它占用的内容。但只要有代码在引用对象URL,内存就不会释放。要手工使用这个方法释放内存。

      var fileList=document.getElementById("file_list");
fileList.onchange=function(event){
var info="",
output=document.getElementById("file_list"),
progress=document.getElementById("progress"),
files=event.target.files,
reader=new FileReader(),
url=window.URL.createObjectURL(files[0]);//返回一个字符串,指向一个内存地址
if(url){
if(/image/.test(files[0].type)){
progress.innerHTML="<img src="+url+">"
}else{
progress.innerHTML=" Not an image.";
}
}else{
progress.innerHTML="your browser doesn't support object URLs.";
}
}

直接把对象URL放在<img>标签中,就省去了把数据先读到javascript中的麻烦。另一方面,<img>标签会招到相应的内存地址,直接读取数据,并将图像显示在页面中。

如果不再需要相应的数据,最好释放它占用的内容。但只要有代码在引用URL,内存就不会释放。要手工释放内存,就要把URL传给window.URL.revokeObjectURL().

window.URL.revokeObjectURL(url);

虽然,页面卸载时会自动释放URL占用的内存,但最好还是手动释放一下,确保尽可能少的占用内存。

支持URL对象的浏览器有IE10+、firefox4+、chrome

 读取拖放的文件
在页面上创建了自定义的放置目标之后,你可以从桌面上把文件拖放到该目标,该目标必须取消dragenter、dragover和drop事件的默认行为。从桌面上把文件拖放到浏览器中也会触发drop事件,而且可以在event.dataTransfer.files中读取到被放置的文件,此时它是一个File对象,与通过文件输入字段取得File对象一样。

例如:

      var droptarget=document.getElementById("droptarget");
function dropEvent(event){
var info="",
files,i,len;
event.preventDefault();//阻止拖放的默认事件
if(event.type=="drop"){
files=event.dataTransfer.files;
i=0;
len=files.length;
while(i<len){
info+=files[i].name+" ("+files[i].type+", "+files[i].size+" bytes)<br>";
i++;
} droptarget.innerHTML=info;
}
}
//给容器添加拖放事件
droptarget.addEventListener("dragenter",dropEvent);
droptarget.addEventListener("dragover",dropEvent);
droptarget.addEventListener("drop",dropEvent);

使用XHR上传文件

最好的做法是以表单提交的方式上传文件,通过使用FormData类型就很容易做到了,创建一个FormData的实例,通过它调用append(键,值)方法并传入相应的File对象作为参数。然后,再把FormData实例传递给XHR的send()方法。

      var droptarget=document.getElementById("droptarget");
function dropEvent(event){
var data,xhr,
files,i,len;
event.preventDefault();//阻止拖放的默认事件
if(event.type=="drop"){
data=new FormData();//创建一个formdata对象
files=event.dataTransfer.files;//读取到被放置的文件
i=0;
len=files.length;
while(i<len){
data.append("file"+i,files[i]);
console.log(files[i]);
i++;
} xhr=new XMLHttpRequest();
xhr.open("post","FileAPIExample06Upload.php",true);
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
console.log(xhr.responseText);
}
}
xhr.send(data);
}
}
//给容器添加拖放事件
droptarget.addEventListener("dragenter",dropEvent);
droptarget.addEventListener("dragover",dropEvent);
droptarget.addEventListener("drop",dropEvent);

上面例子创建了一个FormData对象,与每个文件对应键分别是file0、file1、file2这样的格式。注意,不用额外写任何代码,这些文件就可以作为表单的值提交。而且,也不必使用FileReader,只要传入File对象即可。

Web 计时

页面性能一直都是Web开发人员比较关注的领域。但在实际应用中,度量页面性能的指标,是javascript的Date对象。Web Timing API改变了这个局面,让开发人员通过javascript就能使用浏览器内部的度量结果,给出了页面加载和渲染过程的很多信息,对性能优化非常有价值。本文将详细介绍web Timing API——performance对象。

简述

  Web计时机制的核心是window.performance对象。对页面的所有度量信息,包括那些规范中已经定义的和将来才能确定的,都包含在这个对象里面。performance对象包括navigation和timing对象。

window.performance.navigation属性也是一个对象,包含着与页面导航有关的多个属性:

redirectCount:页面加载前的重定向次数;

type:数值常量,表示刚刚发生的导航类型;0:页面第一次加载;1:页面重载过;2:页面是否通过“后退”或“前进”按钮打开的;

      console.log(window.performance.navigation.redirectCount);//页面重定向次数
console.log(window.performance.navigation.type);//导航类型

window.performance.timing属性也是一个对象,但这个对象的属性都是时间戳(从软件纪元开始经过的毫秒数),这个独享包括以下属性:

navigationStart:开始导航到当前页面的时间;

unloadEventStart:前一个页面的unload事件的开始时间;(只有在前一个页面域当前页面来自同一个域时,这个属性才有值,否则,值为0)

unloadEventEnd:前一个页面的unload事件结束的时间;(只有在前一个页面域当前页面来自同一个域时,这个属性才有值,否则,值为0)  

redirectStart:到当前页面的重定向开始的时间;(只有在前一个页面域当前页面来自同一个域时,这个属性才有值,否则,值为0)

redirectEnd:到当前页面重定向结束的事件;(只有在前一个页面域当前页面来自同一个域时,这个属性才有值,否则,值为0)

fetchStart:开始通过HTTP GET取得页面的时间;

domainLookupStart:开始查询当前页面DNS的时间;

domainLookupEnd:查询当前页面DNS结束时间;

connectStart:浏览器尝试连接服务器的时间;

connectEnd:浏览器成功连接到服务器的时间;

secureConnectionStart:浏览器尝试以SSL方式连接服务器的时间。不能使用SSL方式连接时,这个属性值为0;

requestStart:浏览器开始请求页面的时间。

responseStart:浏览器接收到页面第一字节的时间。

responseEnd:浏览器接收到页面所有内容的时间。

domLoading:document.readyState变为“loading”的时间。

domInteractive:document.readyState变为“interactive”的时间。

domContentLoadedEventStart:发生DOMContentLoaded事件的时间。

domContentLoadedEventEnd:DOMContentLoaded事件已经发生且执行完所有事件处理程序的时间。

domComplete:document.readyState变为“complete”的时间。

loadEventStart:发生load事件的时间。

loadEventEnd:load事件已经发生且执行完成所有事件处理程序的时间。

      console.log(window.performance.timing.navigationStart);//开始导航到当前页面的时间
console.log(window.performance.timing.unloadEventStart);//前一个页面的unload事件的开始时间
console.log(window.performance.timing.unloadEventEnd);//前一个页面的unload事件结束的时间
console.log(window.performance.timing.redirectStart);//到当前页面的重定向开始的时间
console.log(window.performance.timing.redirectEnd);//到当前页面重定向结束的事件
console.log(window.performance.timing.fetchStart);//开始通过HTTP GET取得页面的时间
console.log(window.performance.timing.domainLookupStart);//开始查询当前页面DNS的时间
console.log(window.performance.timing.domainLookupEnd);//查询当前页面DNS结束时间
console.log(window.performance.timing.connectStart);//浏览器尝试连接服务器的时间
console.log(window.performance.timing.connectEnd);//浏览器成功连接到服务器的时间
console.log(window.performance.timing.secureConnectionStart);//浏览器尝试以SSL方式连接服务器的时间。不能使用SSL方式连接时,这个属性值为0;
console.log(window.performance.timing.requestStart);//浏览器开始请求页面的时间
console.log(window.performance.timing.responseStart);//浏览器接收到页面第一字节的时间
console.log(window.performance.timing.responseEnd);//浏览器接收到页面所有内容的时间
console.log(window.performance.timing.domLoading);//document.readyState变为“loading”的时间
console.log(window.performance.timing.domInteractive);//document.readyState变为“interactive”的时间。
console.log(window.performance.timing.domContentLoadedEventStart);//发生DOMContentLoaded事件的时间
console.log(window.performance.timing.domContentLoadedEventEnd);//DOMContentLoaded事件已经发生且执行完所有事件处理程序的时间
console.log(window.performance.timing.domComplete);//document.readyState变为“complete”的时间
console.log(window.performance.timing.loadEventStart);//发生load事件的时间
console.log(window.performance.timing.loadEventEnd);//load事件已经发生且执行完成所有事件处理程序的时间。

通过这些值,就可以全面了解页面在被加载到浏览器的过程中都经历了哪些阶段,而哪些阶段可能是影响性能的瓶颈。

Web Workers(多线程)

可以让单线程的js运行多线程。

使用worker

实例化Worker对象并传入要执行的javascript文件名就可以创建一个新的Web Worker。例如:

var worker = new worker("worker.js");

可以向worker.js内传入任何可序列化的对象(调用的是worker的postMessage()方法)

      worker.postMessage({
type:"command",
message:"start"
});

Worker是通过message和error事件与页面进行通信的,来自worker.js的数据保存在event.data中。worker返回的数据也可以是任何能被序列化的值:

      worker.onmessage=function(event){
var data=event.data;
//对数据进行处理
}

Worker不能完成给定的任务时会触发error事件。具体来说,Worker内部的javascript在执行过程中只要遇到错误,就会触发error事件。发生error事件时,事件对象中包含3个属性:

filename、lineno、message,分别表示发生错误的文件名、代码行号和完整的错误信息。

      worker.onerror=function(event){
console.log("Error: "+event.filename+" ("+event.lineno+"): "+event.message);
}

任何时候,只要调用terminate()方法就可以停止Worker的工作。而且,Worker中的代码会立即停止执行,后续的所有过程都不会再发生(包括error和message事件也不会触发)。

      worker.terminate();//立即停止Worker的工作

在worker打开的js内可以向主页面传值,通过postMessage(data)方法,可以传入任何值;

下面是一个综合例子:

      var w,
output=document.getElementById("output");
function startWorker(){
if(typeof Worker!== "undefined"){
if(typeof(w)==="undefined"){
w=new Worker("worker.js");
}
//传给worker.js点数据
w.postMessage({
type:"command",
message:"start"
});
w.onmessage=function(event){
output.innerHTML=event.data;
}
w.onerror=function(event){
console.log("Error: "+event.filename+" ("+event.lineno+"): "+event.message);
}
}else{
output.innerHTML="浏览器不支持worker";
}
}
function stopWorker(){
w.terminate();
}

以下是worker.js内的代码:

// worker.js接收页面传来的数据
self.onmessage=function(event){
console.log(event.data);
}
self.onerror=function(){
console.log("接收页面传来的值失败");
}
function timedCount(){
for(let i=0,len=100000000;i<len;i++){
if(i%100000===0){
//this指向worker本身,self也是,但这个worker和页面中的worker不是同一个worker
postMessage(i);
// this.postMessage(i);
// self.postMessage(i);
} }
}
timedCount();

在woker.js内调用close()方法,可以停止worker运行

self.close();
this.close();
close();

Worker全局作用域

关于web Worker 最重要的是要知道它所执行的javascsript代码完全在另一个作用域中,与当前网页的代码不共享作用域。在web worker中,同样有一个全局对象和其它对象以及方法。但是,web Worker中的全局对象是worker对象本身。也就是说,在这个特殊的全局作用域中,this和self引用的都是worker对象。为便于处理数据,web worker本身也是一个最小化的运行环境。

1、最小化的navigator对象,包括onLine、appName、appVersion、userAgent和platform属性;

2、只读的location对象;

3、setTimeout()、setInterval()、clearTimeout()、clearInterval();

4、XMLHttpRequest构造函数;

显然,web worker的运行环境与页面环境相比,功能是相当有限的。

包含其它脚本

无法在worker中动态创建script标签,但是可以调用importScripts()方法,可以引入其它js脚本。例如:

importScripts("file1.js","file2.js");

即使files2.js比file1.js先下载完,但是执行的时候还是会按照顺序执行。

新兴的API(fileReader、geolocation、web计时、web worker)的更多相关文章

  1. 《JavaScript高级程序设计》笔记:新兴的API

    requestAnimationFrame() 大多数电脑显示器的刷新频率60HZ,大概相当于每秒钟重绘60次.因此,最平滑动画的最佳循环间隔是1000ms/60,约等于17ms. mozReques ...

  2. web计时机制——performance对象

    前面的话 页面性能一直都是Web开发人员最关注的领域.但在实际应用中,度量页面性能的指标,是提高代码复杂程度和巧妙地使用javascript的Date对象.Web Timing API改变了这个局面, ...

  3. web计时机制

    前面的话 页面性能一直都是Web开发人员比较关注的领域.但在实际应用中,度量页面性能的指标,是javascript的Date对象.Web Timing API改变了这个局面,让开发人员通过javasc ...

  4. [转]web计时机制——performance对象

    页面性能一直都是Web开发人员比较关注的领域.但在实际应用中,度量页面性能的指标,是javascript的Date对象.Web Timing API改变了这个局面,让开发人员通过javascript就 ...

  5. Difference between WCF and Web API and WCF REST and Web Service

    The .Net framework has a number of technologies that allow you to create HTTP services such as Web S ...

  6. WCF 、Web API 、 WCF REST 和 Web Service 的区别

    WCF .Web API . WCF REST 和 Web Service 的区别 The .Net framework has a number of technologies that allow ...

  7. Web API WinForm使用HttpClient呼叫Web API

    前言 之前几篇文章已经介绍了 Web 与 Web API 的使用方式,接下来将介绍如何在 Windows Form 呼叫 Web API 的方法,要在 WinForm 中使用 Web API 的话,除 ...

  8. 【转载】ASP.NET MVC Web API 学习笔记---第一个Web API程序

    1. Web API简单说明 近来很多大型的平台都公开了Web API.比如百度地图 Web API,做过地图相关的人都熟悉.公开服务这种方式可以使它易于与各种各样的设备和客户端平台集成功能,以及通过 ...

  9. ASP.NET MVC Web API 学习笔记---第一个Web API程序

    http://www.cnblogs.com/qingyuan/archive/2012/10/12/2720824.html GetListAll /api/Contact GetListBySex ...

随机推荐

  1. npm国内镜像

    国内使用默认的源安装较慢,镜像使用方法(三种办法任意一种都能解决问题,建议使用第三种,将配置写死,下次用的时候配置还在): 1.通过config命令 npm config set registry h ...

  2. Python匿名函数——lambda表达式

    如果要定义的函数很简单,一个return语句就能搞定,可以使用lambda表达式来定义, lambda表达式的语法如下: lambda parameters: expression lambda表达式 ...

  3. Linux软件安装中RPM与YUM 区别和联系

    .tc-nav-row{ height:38px; margin: 8px 15px; } .tc-nav-tab{ text-align: center; color:#333333; line-h ...

  4. firadisk 把 win7(32位) 装入 VHD :仅仅支持内存模式:--mem

    关键1:对于 win7(32位)来说,还可以在设备管理器内,通过添加“过时”硬件的方式导入wvblk驱动. 附件: grub4dos firadisk驱动

  5. Tensorflow读写TFRecords文件

    在使用slim之类的tensorflow自带框架的时候一般默认的数据格式就是TFRecords,在训练的时候使用TFRecords中数据的流程如下:使用input pipeline读取tfrecord ...

  6. [Android] 基于 Linux 命令行构建 Android 应用(三):构建流程

    Android 应用的构建过程就是将 Android 项目中的文件和资源进行编译和打包,最后将结果输出到 .apk 文件..apk 文件是保存二进制文件的容器,它包含了运行安卓应用所需的所有信息,例如 ...

  7. Python实现C代码统计工具(四)

    目录 Python实现C代码统计工具(四) 标签: Python 计时 持久化 声明 运行测试环境 一. 自定义计时函数 1.1 整个程序计时 1.2 代码片段计时 1.3 单条语句计时 二. 性能优 ...

  8. 基于IOS上MDM技术相关资料整理及汇总

    (转自:http://www.mbaike.net/special/1542.html) 一.MDM相关知识:MDM (Mobile Device Management ),即移动设备管理.在21世纪 ...

  9. C# HTTPServer和OrleansClient结合

    using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using ...

  10. NHibernate.3.0.Cookbook第一章第五节Setting up a base entity class

    Setting up a base entity class设置一个实体类的基类 在这节中,我将给你展示怎么样去为我们的实体类设置一个通用的基类. 准备工作 完成前面三节的任务 如何去做 1.在Ent ...