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 相关文章推荐
兼容ie和firefox js关闭代码
Dec 11 Javascript
高性能WEB开发 flush让页面分块,逐步呈现 flush让页面分块,逐步呈现
Jun 19 Javascript
jQuery源码分析-03构造jQuery对象-工具函数
Nov 14 Javascript
jQuery选择器源码解读(五):tokenize的解析过程
Mar 31 Javascript
JavaScript常用字符串与数组扩展函数小结
Apr 24 Javascript
bootstrap3 兼容IE8浏览器!
May 02 Javascript
vue 动态绑定背景图片的方法
Aug 10 Javascript
说说如何利用 Node.js 代理解决跨域问题
Apr 22 Javascript
vue2.0+SVG实现音乐播放圆形进度条组件
Sep 21 Javascript
解决Vue在Tomcat8下部署页面不加载的问题
Nov 12 Javascript
jquery实现吸顶导航效果
Jan 08 jQuery
Vue Elenent实现表格相同数据列合并
Nov 30 Vue.js
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简单实现快速排序的方法
2015/04/04 PHP
yii框架redis结合php实现秒杀效果(实例代码)
2017/10/26 PHP
php微信开发之关键词回复功能
2018/06/13 PHP
IE6下CSS图片缓存问题解决方法
2010/12/09 Javascript
基于jquery实现漂亮的动态信息提示效果
2011/08/02 Javascript
纯javascript响应式树形菜单效果
2015/11/10 Javascript
js实现图片上传预览原理分析
2017/07/13 Javascript
详解如何在vue-cli中使用vuex
2018/08/07 Javascript
深入浅析Node.js 事件循环、定时器和process.nextTick()
2018/10/22 Javascript
微信小程序Echarts覆盖正常组件问题解决
2019/07/13 Javascript
《javascript设计模式》学习笔记五:Javascript面向对象程序设计工厂模式实例分析
2020/04/08 Javascript
Vant 中的Toast设置全局的延迟时间操作
2020/11/04 Javascript
nuxt静态部署打包相对路径操作
2020/11/06 Javascript
基于Vue3.0开发轻量级手机端弹框组件V3Popup的场景分析
2020/12/30 Vue.js
[01:07:22]2014 DOTA2华西杯精英邀请赛 5 24 DK VS VG加赛
2014/05/26 DOTA
跟老齐学Python之不要红头文件(1)
2014/09/28 Python
Python实现的端口扫描功能示例
2018/04/08 Python
Django项目中包含多个应用时对url的配置方法
2018/05/30 Python
python通过微信发送邮件实现电脑关机
2018/06/20 Python
Python提取频域特征知识点浅析
2019/03/04 Python
Python2.7版os.path.isdir中文路径返回false的解决方法
2019/06/21 Python
解决django同步数据库的时候app models表没有成功创建的问题
2019/08/09 Python
python实现文件批量编码转换及注意事项
2019/10/14 Python
Python IDE环境之 新版Pycharm安装详细教程
2020/03/05 Python
Django REST framwork的权限验证实例
2020/04/02 Python
Python requests.post方法中data与json参数区别详解
2020/04/30 Python
Python实现树莓派摄像头持续录像并传送到主机的步骤
2020/11/30 Python
pandas 数据类型转换的实现
2020/12/29 Python
通用的Django注册功能模块实现方法
2021/02/05 Python
HTML5 Web Database 数据库的SQL语句的使用方法
2012/12/09 HTML / CSS
HTML5 History API 实现无刷新跳转
2016/01/11 HTML / CSS
罗技英国官方网站:Logitech UK
2020/11/03 全球购物
入党转预备思想汇报
2014/01/07 职场文书
大学生个人先进事迹材料范文
2014/05/03 职场文书
收入证明怎么写
2015/06/12 职场文书
MySQL存储过程及语法详解
2022/08/05 MySQL