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 相关文章推荐
将HTML自动转为JS代码
Jun 26 Javascript
JavaScript 三种不同位置代码的写法
Oct 25 Javascript
javascript列表框操作函数集合汇总
Nov 28 Javascript
file控件选择上传文件确定后触发的js事件是哪个
Mar 17 Javascript
JavaScript中日期的相关操作方法总结
Oct 24 Javascript
es6学习笔记之Async函数基本教程
May 11 Javascript
解决vue里碰到 $refs 的问题的方法
Jul 13 Javascript
Vuex 快速入门(简单易懂)
Sep 20 Javascript
微信小程序制作表格的方法
Feb 14 Javascript
jQuery实现评论模块
Aug 19 jQuery
vue解决跨域问题(推荐)
Nov 10 Javascript
uniapp微信小程序:key失效的解决方法
Jan 20 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
PHPCMS的使用小结
2010/09/20 PHP
php使用递归计算文件夹大小
2014/12/24 PHP
PHP批量查询WordPress留言者E-mail地址实现方法
2015/02/15 PHP
PHP将URL转换成短网址的算法分享
2016/09/13 PHP
php 从指定数字中获取随机组合的简单方法(推荐)
2017/04/05 PHP
laravel框架语言包拓展实现方法分析
2019/11/22 PHP
正则表达式判断是否存在中文和全角字符和判断包含中文字符串长度
2008/09/27 Javascript
javascript instanceof 内部机制探析
2010/10/15 Javascript
读jQuery之十四 (触发事件核心方法)
2011/08/23 Javascript
Jquery遍历checkbox获取选中项value值的方法
2014/02/13 Javascript
详解jQuery UI库中文本输入自动补全功能的用法
2016/04/23 Javascript
jQuery ajax的功能实现方法详解
2017/01/06 Javascript
AngularJS监听路由变化的方法
2017/03/07 Javascript
React中的render何时执行过程
2018/04/13 Javascript
vant(ZanUi)结合async-validator实现表单验证的方法
2018/12/06 Javascript
vue动态渲染svg、添加点击事件的实现
2020/03/13 Javascript
vue自定义树状结构图的实现方法
2020/10/18 Javascript
[01:00:53]OG vs IG 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python文档生成工具pydoc使用介绍
2015/06/02 Python
python实现文本文件合并
2015/12/29 Python
遍历python字典几种方法总结(推荐)
2016/09/11 Python
详解python中的文件与目录操作
2017/07/11 Python
django数据库自动重连的方法实例
2019/07/21 Python
python设计tcp数据包协议类的例子
2019/07/23 Python
python控制台实现tab补全和清屏的例子
2019/08/20 Python
PyCharm 无法 import pandas 程序卡住的解决方式
2020/03/09 Python
解决matplotlib.pyplot在Jupyter notebook中不显示图像问题
2020/04/22 Python
Python Socket TCP双端聊天功能实现过程详解
2020/06/15 Python
python制作一个简单的gui 数据库查询界面
2020/11/19 Python
Nordgreen手表德国官方网站:丹麦极简主义手表
2019/10/31 全球购物
Zalando Lounge瑞士:时尚与生活方式购物俱乐部
2020/03/12 全球购物
机关门卫岗位职责
2013/12/30 职场文书
刑事上诉状(量刑过重)
2015/05/23 职场文书
使用Redis实现点赞取消点赞的详细代码
2022/03/20 Redis
排查MySQL生产环境索引没有效果
2022/04/11 MySQL
解决vue自定义组件@click点击失效问题
2022/04/30 Vue.js