【第三周读书笔记】浅谈node.js中的异步回调和用js-xlsx操作Excel表格
在初步学习了node.js之后,我发现他的时序问题我一直都很模糊不清,所以我专门学习了一下这一块。
首先我们来形象地理解一下进程和线程:
进程:CPU执行任务的模块。线程:模块中的最小单元。
例如:cpu比作我们每个人,到饭点吃饭了。可以点很多菜(cpu中的进程):宫保鸡丁,鱼香肉丝,酸辣土豆丝。每样菜具体包含了哪些内容(cpu每个进程中的线程):宫保鸡丁(详情:黄瓜、胡萝卜、鸡肉、花生米)。而详情构成了宫保鸡丁这道菜,吃了以后不饿。就可以干活了,cpu中的进程里的线程也是同理。当线程完成自己的内容将结果返回给进程,进程返回给cpu的时候。cpu就能处理日常需求。
单进程单线程:一盘炒苦瓜,里面只有苦瓜。
单进程多线程:一盘宫保鸡丁,里面有黄瓜、胡萝卜、鸡肉、花生米
JS中负责解释和执行javascript的线程只有一个,叫做主线程。
还存在其他的线程:处理AJAX请求的线程,处理DOM事件的线程,定时器线程,读写文件的线程。叫做工作线程。
主线程只有一个,那么如果按正常想法只能同步执行,是不是就会造成block的现象:在菜鸟教程中它写了这样一个很形象化的例子:
主线程:“你好,AJAX线程。请你帮我发个HTTP请求吧,我把请求地址和参数都给你了。”
AJAX线程:“......”
主线程::“喂,AJAX线程,你怎么不说话?”
AJAX线程:“......”
主线程::“喂!喂喂喂!”
AJAX线程:“......”
(一炷香的时间后)
主线程::“喂!求你说句话吧!”
AJAX线程:“主线程,不好意思,我在工作的时候不能说话。你的请求已经发完了,拿到响应数据了,给你。”
很明显这样效率是非常低下的,但是node.js非常聪明,虽然只有一条主线程,但是它采用了事件回调,消息队列这样一种工作模式,来异步执行程序,减少了block。
主线程:“你好,AJAX线程。请你帮我发个HTTP请求吧,我把请求地址和参数都给你了。”
AJAX线程:“好的,主线程。我马上去发,但可能要花点儿时间呢,你可以先去忙别的。”
主线程::“谢谢,你拿到响应后告诉我一声啊。”
(接着,主线程做其他事情去了。一顿饭的时间后,它收到了响应到达的通知。)
主线程发出一个异步请求,相应的工作线程接受请求并告知主线程已收到(异步函数返回);主线程可以继续执行后面的代码,同时工作线程执行异步任务;工作线程完成工作后,通知主线程;主线程收到通知后,执行一定的动作(调用回调函数)。
工作线程在异步操作完成后通知主线程的过程:工作线程将消息放到消息队列,主线程通过事件循环过程去取信息。实际上,主线程只会从消息队列里面取信息,执行信息,再取信息,再执行。当消息队列为空时,就会等待消息队列变成非空。只有当前消息执行完成后,才会去取下一个信息,这就是事件循环机制。
事件驱动程序:当server接收到请求,就把它关闭然后处理,然后去服务下一个请求。当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。
如果对这个事件循环机制还是不太理解的话,这里推荐一个极其好的网站:
https://2014.jsconf.eu/speakers/philip-roberts-what-the-heck-is-the-event-loop-anyway.html
讲的特别明白。
一些Excel中的基本概念和操作:
workbook对象:整份Excel文档,用js-xlsx读取excel文档后获得workbook对象。
workbook的结构:
{
sheetNames:['sheet1'],['sheet2],
sheets:{
'sheet1':{ //worksheet 每张表对应的就是worksheet对象。
'A1':{},
'A2':{},//CELL单元格
}
}
}
①XLSX.read读取Excel数据,返回workbook。
ex. workbook = XLSX.read(excelData,{type:'base64'});
②XLSX.readFile打开Excel文件,返回workbook。
ex. workbook = XLSX.readFile(filename,opts);
③workbook.sheetNames获取worksheet的名字。
ex. var sheetNames = workbook.sheetNames; //返回['sheet1','sheet2']
④workbook.sheets[xxx]通过worksheet的名字来获取worksheet。
ex. var worksheet = workbook.sheets[sheetNames[0]];
⑤worksheet[address]操作单元格
ex.
let a1 = worksheet['A1']; //获取A1单元格对象,返回{v:'hello',t:'s'}
a1.v //返回‘hello'
⑥XLSX.utils.sheet_to_json针对单个worksheet获取表格数据转换为json格式。
ex.
XLSX.utils.sheet_to_json//针对单个worksheet,返回json数据。
⑦XLSX.writeFile(workbook,filename)生成新的Excel文件。
ex. XLSX.writeFile(wb, 'output.xlsx');