这里有新鲜出炉的 Node.JS 入门教程,程序狗速度看过来!
Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台, 用来方便地搭建快速的 易于扩展的网络应用 · Node.js 借助事件驱动, 非阻塞 I/O 模型变得轻量和高效, 非常适合 运行在分布式设备 的 数据密集型 的实时应用
这篇文章首先给大家介绍了为什么要用异步 API,其次 node.js 异步 api 在使用过程有一些什么样的限制呢,对于这个问题我们下面来看看这篇关于 node.js 异步的介绍分析吧,有需要的可以参考借鉴。
用异步 API 的原因
异步的概念之所以首先在 web2.0 中火起来, 是因为在浏览器中 Javascript 在单线程上执行, 而且他还与 UI 渲染公用一个线程. 这意味着 Javascript 在执行的时候 UI 渲染和响应是处于停滞状态的. 为了用户体验更好而采取异步的方式 (当然, 这在所谓的单线程语言中) 不阻塞主线程继续响应用户操作. 这属于用户体验的范畴.
同样的, 如果有其他语言经验的工程师当然也明白, CPU 在线程间切换是需要消耗大量的时间的 (主要为上下文之间的切换和缓存), 所以提高效率也是使用异步 API 的理由.
当然, 这些并不是绝对的正确, 只是人人都这么说而已. 因为如果创建多线程的开销小于并行执行, 那么多线程的方式是首选, 这时常被认为是 CPU 密集型的处理任务.
总之, 异步 IO 或者说异步 API 可以算作 Node 的特色, 因为它是收个大规模将异步 IO 应用在应用层上的平台, 它力求在单线程上将资源分配得更高效.
关于 Promise
这里, 本文并不打算详细讲解 Promise 的用法, 只简单说明 Promise 的一些 API 和试用范围:
- //结合nodejs的fs.readdir函数创建一个原生Promise
- var promiseTask = new Promise(function(resolve, reject) {
- fs.readdir('/var/www',
- function(err, files) {
- if (!err) {
- resolve(files);
- } else {
- reject(err);
- }
- });
- });
- promiseTask.then(function(files) {
- console.log('内容为:' + files);
- return files; //为了接着演示其他API 这里return之后 可继续使用then定义下一步操作函数.
- });
- promiseTask.
- catch(function(err) {
- console.log('报错为:' + err);
- });
如何等待多个 Promise 完成
- //接上面
- promiseTask.then(function(files){
- var readFilsePromiseList = files.map(function(file,index){
- return new Promise(function(resolve,reject){
- fs.readFile(file,'utf-8',function(err,str){
- if(!err){
- resolve(str)
- }
- else{
- reject(err)
- }
- });
- });
- });
- return Promise.all(readFilsePromiseList);
- }).then(function(fileStrArray){
- console.log('所谓文件读取完毕:'+fileStrArray);
- });
这段代码确实表现出了 nodejs 开发的优雅之处.
那么问题在哪
目前再优雅的语言依然依托于操作系统, 也就是说, 系统的限制依然存在:
我不知道能不能把这个错误解释成文件操作句柄耗尽, 但大概意思本文希望各位能够理解, 操作系统并不是可以同时打开无限多个文件.
还有这种:
这个很好理解, 内存耗尽. 当然, 内存限制, 可以通过加入以下两个运行参数调整:
- node --max-old-space-size=8192 ./index.js #单位MB
- node --max-new-space-size=2048 ./index.js #单位KB
上述参数在 V8 初始化时生效, 一旦生效不可动态变更.
很多人可能会提出, 这两个限制在其他语言中一样存在. 是的, 其他语言一样存在.
但是其他语言强大的 GC 或多线程的编程模型可以让工程师们能在申请系统资源之后及时释放.
而 nodejs 中虽然也可手动释放不需要的系统资源, 但真的可以做到引用程序里的每一个操作都能及时释放吗?
举个栗子: nodejs 的 redis 包 (npm install redis) 并不提供同步的操作方法.
这意味着开发的过程要考虑更多的流程控制, 很遗憾, 单线程体系的 nodejs 并不擅长这个, 正是因为本质上没有多线程的概念, 没有锁机制, 也不可能包含通常意义上的信号量机制, 结果就是工程师根本不知道什么时候去手动释放资源.
除非对自己项目有绝对的掌控权, 不使用任何使用异步 API 的第三方包.
所以, 目前的结论就是, Promise 只是一种开发的技巧, 了解这些, 并不适用于所有开发场景.
总结
以上就是关于 node.js 异步 API 和其局限性的全部内容,希望这篇文章对大家能有所帮助。如果有疑问大家可以留言交流。
来源: http://www.phperz.com/article/17/0628/332092.html