深入分析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 相关文章推荐
由prototype_1.3.1进入javascript殿堂-类的初探
Nov 06 Javascript
js 省地市级联选择
Feb 07 Javascript
jQuery 操作option的实现代码
Mar 03 Javascript
js动态添加删除,后台取数据(示例代码)
Nov 25 Javascript
angularJS Provider、factory、service详解及实例代码
Sep 21 Javascript
require、backbone等重构手机图片查看器
Nov 17 Javascript
react-native-fs实现文件下载、文本存储的示例代码
Sep 22 Javascript
关于Google发布的JavaScript代码规范你要知道哪些
Apr 04 Javascript
Bootstrap模态对话框用法简单示例
Aug 31 Javascript
详解Angular6学习笔记之主从组件
Sep 05 Javascript
vue elementUI 表单校验的实现代码(多层嵌套)
Nov 06 Javascript
JS字符串补全方法padStart()和padEnd()
May 27 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
基于mysql的论坛(2)
2006/10/09 PHP
PHP+MYSQL 出现乱码的解决方法
2008/08/08 PHP
php pcntl_fork和pcntl_fork 的用法
2009/04/13 PHP
php print EOF实现方法
2009/05/21 PHP
实用的简单PHP分页集合包括使用方法
2013/10/21 PHP
Laravel中服务提供者和门面模式的入门介绍
2017/11/06 PHP
XAMPP升级PHP版本实现步骤解析
2020/09/04 PHP
在textarea文本域中显示HTML代码的方法
2007/03/06 Javascript
javascript innerHTML、outerHTML、innerText、outerText的区别
2008/11/24 Javascript
jQuery中与toggleClass等价的程序段 以及未来学习的方向
2010/03/18 Javascript
jQuery AJAX实现调用页面后台方法和web服务定义的方法分享
2012/03/01 Javascript
深入理解JavaScript高级之词法作用域和作用域链
2013/12/10 Javascript
js的参数有长度限制吗?发现不能超过2083个字符
2014/04/20 Javascript
现代 JavaScript 开发编程风格Idiomatic.js指南中文版
2014/05/28 Javascript
js实现双击图片放大单击缩小的方法
2015/02/17 Javascript
JavaScript原生对象之String对象的属性和方法详解
2015/03/13 Javascript
JS实时弹出新消息提示框并有提示音响起的实现代码
2016/04/20 Javascript
Vue.js基础知识汇总
2016/04/27 Javascript
浅谈vuejs实现数据驱动视图原理
2018/02/23 Javascript
JS大坑之19位数的Number型精度丢失问题详解
2019/04/22 Javascript
微信小程序HTTP接口请求封装代码实例
2019/09/05 Javascript
JS字符串补全方法padStart()和padEnd()
2020/05/27 Javascript
[02:18]《我与DAC》之工作人员:为了热爱DOTA2的玩家们
2018/03/28 DOTA
[03:06]3分钟带你回顾DOTA2完美盛典&完美大师赛
2017/12/06 DOTA
[00:08]DOTA2勇士令状等级奖励“天外飞星”
2019/05/24 DOTA
最大K个数问题的Python版解法总结
2016/06/16 Python
python ffmpeg任意提取视频帧的方法
2020/02/21 Python
Python Scrapy多页数据爬取实现过程解析
2020/06/12 Python
Django配置Bootstrap, js实现过程详解
2020/10/13 Python
PHP两种查询函数array/row的区别
2013/06/03 面试题
房地产开发计划书
2014/01/10 职场文书
学生会招新策划书
2014/02/14 职场文书
2014年向国旗敬礼活动方案
2014/09/27 职场文书
导游词之平津战役纪念馆
2019/11/04 职场文书
Vue.Draggable实现交换位置
2022/04/07 Vue.js
Golang并发工具Singleflight
2022/05/06 Golang