深入分析node.js的异步API和其局限性


Posted in Javascript onSeptember 05, 2016

用异步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.js的异步API和其局限性

我不知道能不能把这个错误解释成文件操作句柄耗尽,但大概意思本文希望各位能够理解,操作系统并不是可以同时打开无限多个文件.

还有这种:

深入分析node.js的异步API和其局限性

这个很好理解,内存耗尽. 当然,内存限制,可以通过加入以下两个运行参数调整:

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和其局限性的全部内容,希望这篇文章对大家能有所帮助。如果有疑问大家可以留言交流。

Javascript 相关文章推荐
拖拉表格的JS函数
Nov 20 Javascript
js控制href内容的连接内容的变化示例
Apr 30 Javascript
PHPMyAdmin导入时提示文件大小超出PHP限制的解决方法
Mar 30 Javascript
jquery+php实现滚动的数字特效
Nov 29 Javascript
简单理解JavaScript中的封装与继承特性
Mar 19 Javascript
基于BootStrap栅格栏系统完成网站底部版权信息区
Dec 23 Javascript
bootstrap模态框远程示例代码分享
May 22 Javascript
常见的浏览器Hack技巧整理
Jun 29 Javascript
vue-cli3 配置开发与测试环境详解
May 17 Javascript
layer.msg()去掉默认时间,实现手动关闭的方法
Sep 12 Javascript
Vue 使用beforeEach实现登录状态检查功能
Oct 31 Javascript
详解vue中在循环中使用@mouseenter 和 @mouseleave事件闪烁问题解决方法
Apr 07 Javascript
点击页面任何位置隐藏div的实现方法
Sep 05 #Javascript
JS锚点的设置与使用方法
Sep 05 #Javascript
jquery基本选择器匹配多个元素的实现方法
Sep 05 #Javascript
Vue.js实现一个自定义分页组件vue-paginaiton
Sep 05 #Javascript
jquery层级选择器(匹配父元素下的子元素实现代码)
Sep 05 #Javascript
Vue.js每天必学之计算属性computed与$watch
Sep 05 #Javascript
jQuery实现的导航下拉菜单效果示例
Sep 05 #Javascript
You might like
如何使用FireFox插件FirePHP调试PHP
2013/07/23 PHP
用PHP实现弹出消息提示框的两种方法
2013/12/17 PHP
ThinkPHP添加更新标签的方法
2014/12/05 PHP
Mac系统下使用brew搭建PHP(LNMP/LAMP)开发环境
2015/03/03 PHP
PHP获取毫秒级时间戳的方法
2015/04/15 PHP
浅谈PHP中output_buffering
2015/07/13 PHP
laravel实现简单用户权限的示例代码
2019/05/28 PHP
innerHTML,outerHTML,innerTEXT三者之间的区别
2007/01/28 Javascript
JavaScript更改class和id的方法
2008/10/10 Javascript
jquery 分页控件实现代码
2009/11/30 Javascript
JAVASCRIPT实现的WEB页面跳转以及页面间传值方法
2010/05/13 Javascript
利用jQuery实现可输入搜索文字的下拉框
2013/10/23 Javascript
JavaScript 巧学巧用
2017/05/23 Javascript
Angular模板表单校验方法详解
2017/08/11 Javascript
通过V8源码看一个关于JS数组排序的诡异问题
2017/08/14 Javascript
浅谈webpack编译vue项目生成的代码探索
2017/12/11 Javascript
jQuery实现为table表格动态添加或删除tr功能示例
2019/02/19 jQuery
JS深入学习之数组对象排序操作示例
2020/05/01 Javascript
[02:48]DOTA2英雄基础教程 暗夜魔王
2013/12/12 DOTA
python中List的sort方法指南
2014/09/01 Python
Django Highcharts制作图表
2016/08/27 Python
利用python实现命令行有道词典的方法示例
2017/01/31 Python
Python 专题六 局部变量、全局变量global、导入模块变量
2017/03/20 Python
详解python使用pip安装第三方库(工具包)速度慢、超时、失败的解决方案
2018/12/02 Python
Python闭包和装饰器用法实例详解
2019/05/22 Python
解决django后台样式丢失,css资源加载失败的问题
2019/06/11 Python
python基于递归解决背包问题详解
2019/07/03 Python
python修改FTP服务器上的文件名
2019/09/11 Python
深入浅析Python 函数注解与匿名函数
2020/02/24 Python
CSS3弹性布局内容对齐(justify-content)属性使用详解
2017/07/31 HTML / CSS
英国第一的市场和亚马逊替代品:OnBuy
2019/03/16 全球购物
薇姿法国官网:Vichy法国
2021/01/28 全球购物
酒店实习个人鉴定
2013/12/07 职场文书
低碳环保标语
2014/06/12 职场文书
2015秋季开学演讲稿范文
2015/07/16 职场文书
oracle表分区的概念及操作
2021/04/24 Oracle