JavaScript中使用Callback控制流程介绍


Posted in Javascript onMarch 16, 2015

javascript中随处可见的callback对于流程控制来说是一场灾难,缺点显而易见:

1.没有显式的return,容易产生多余流程,以及由此引发的bug。
2.造成代码无限嵌套,难以阅读。

下面就来说说怎么解决避免上述的问题。

第一个问题是一个习惯问题,在使用callback的时候往往会让人忘了使用return,这种情况在使用coffee-script的时候尤甚(虽然它在编译成javascript时会自行收集最后的数据作为返回值,但是这个返回值并不一定代表你的初衷)。看看下面的例子。

a = (err, callback)->

  callback() if err?

  console.log 'you will see me'
b = ->

  console.log 'I am a callback'
a('error', b)

在这种所谓”error first”的代码风格中,显然我们不希望出错时方法a中的后续代码仍然被执行,但是又不希望用throw来让整个进程挂掉(要死也得优雅的死嘛~),那么上面的代码就会产生bug。

一种解决方案就是老老实实的写if...else...,但是我更倾向于下面的做法:

a = (err, callback)->

  return callback() if err?

  console.log 'you will not see me'
b = ->

  console.log 'I am a callback'
a('error', b)

javascript异步方法中的返回值大多没什么用处,所以这里用return充当一个流程控制的角色,比if...else...更少的代码,但是更加清晰。

第二个问题是娘胎里带来的,很难根除。

一种不错的方法是使用一些流程控制模块来将代码显得更加有条理,比如async就是一个不错的模块,提供了一系列的接口,包括迭代,循环,和一些条件语句,甚至还包含了一个队列系统。下面的例子可以表名两种写法的优劣

#normal
first = (callback)->

  console.log 'I am the first function'

  callback()
second = (callback)->

  console.log 'I am the second function'

  callback()
third = ()->

  console.log 'I am the third function'
first ->

  second ->

    third()
# use async
async = require('async')
async.waterfall [

  first,

  second,

  third

], (err)->

作为睿智的你,会选择哪一种呢。

Javascript 相关文章推荐
Draggable Elements 元素拖拽功能实现代码
Mar 30 Javascript
js中方法重载如何实现?以及函数的参数问题
Aug 01 Javascript
jQuery Animation实现CSS3动画示例介绍
Aug 14 Javascript
jQuery+css3动画属性制作猎豹浏览器宽屏banner焦点图
Mar 16 Javascript
javascript实现删除前弹出确认框
Jun 04 Javascript
关于JavaScript作用域你想知道的一切
Feb 04 Javascript
AngularJS 指令详细介绍
Jul 27 Javascript
原生js实现倒计时功能(多种格式调用)
Jan 12 Javascript
jquery实现回车键触发事件(实例讲解)
Nov 21 jQuery
浅谈Webpack自动化构建实践指南
Dec 18 Javascript
Vue 拦截器对token过期处理方法
Jan 23 Javascript
Vuex modules模式下mapState/mapMutations的操作实例
Oct 17 Javascript
jquery图片切换插件
Mar 16 #Javascript
JavaScript中的方法重载实例
Mar 16 #Javascript
jquery中attr和prop的区别分析
Mar 16 #Javascript
JavaScript中扩展Array contains方法实例
Aug 23 #Javascript
JavaScript中消除闭包的一般方法介绍
Mar 16 #Javascript
jQuery实现的支持IE的html滑动条
Mar 16 #Javascript
JavaScript计算两个日期时间段内日期的方法
Mar 16 #Javascript
You might like
浅析PHP中的UNICODE 编码与解码
2013/06/29 PHP
PHP利用APC模块实现文件上传进度条的方法
2015/01/26 PHP
php HTML无刷新提交表单
2016/04/05 PHP
PHP实现防盗链的方法分析
2017/07/25 PHP
在云虚拟主机部署thinkphp5项目的步骤详解
2017/12/21 PHP
laravel框架实现去掉URL中index.php的方法
2019/10/12 PHP
jQuery toggle()设置CSS样式
2009/11/05 Javascript
js+JQuery返回顶部功能如何实现
2012/12/03 Javascript
Javascript中的异步编程规范Promises/A详细介绍
2014/06/06 Javascript
jquery实现键盘左右翻页特效
2015/04/30 Javascript
JavaScript中Number.MAX_VALUE属性的使用方法
2015/06/04 Javascript
javascript RegExp 使用说明
2016/05/21 Javascript
jQuery获取select选中的option的value值实现方法
2016/08/29 Javascript
nodeJs内存泄漏问题详解
2016/09/05 NodeJs
Bootstrap基本组件学习笔记之进度条(15)
2016/12/08 Javascript
Node.js 8 中的重要新特性
2017/06/28 Javascript
angularjs2中父子组件的数据传递的实例代码
2017/07/05 Javascript
Vue中的无限加载vue-infinite-loading的方法
2018/04/08 Javascript
javascript中undefined的本质解析
2019/07/31 Javascript
微信小程序模板消息限制实现无限制主动推送的示例代码
2019/08/27 Javascript
小程序中设置缓存过期的实现方法
2020/01/14 Javascript
JavaScript浅层克隆与深度克隆示例详解
2020/09/01 Javascript
基于js实现的图片拖拽排序源码实例
2020/11/04 Javascript
Python实现的爬虫功能代码
2017/06/24 Python
分享给Python新手们的几道简单练习题
2017/09/21 Python
mvc框架打造笔记之wsgi协议的优缺点以及接口实现
2018/08/01 Python
利用Python产生加密表和解密表的实现方法
2019/10/15 Python
Keras预训练的ImageNet模型实现分类操作
2020/07/07 Python
CSS3实现任意图片lowpoly动画效果实例
2017/05/11 HTML / CSS
使用HTML5拍照示例代码
2013/08/06 HTML / CSS
介绍一下grep命令的使用
2015/06/12 面试题
总经理助理岗位职责
2013/11/08 职场文书
餐厅销售主管职责范本
2014/02/19 职场文书
2015出纳试用期工作总结
2014/12/12 职场文书
企业催款函范本
2015/06/24 职场文书
SONY600GR,国产收音机厂商永远的痛
2022/04/05 无线电