未加星标

【第731期】回调地狱的今生前世@JavaScript

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二05 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏

前言

本文由@rccoder投稿分享。作者总结了四种方式来进行异步操作。

正文从这开始~

1. 讲个笑话

Java 是一门编程语言

2. 异步编程

Java 由于某种原因是被设计为单线程的,同时由于 Java 在设计之初是用于浏览器的 GUI 编程,这也就需要线程不能进行阻塞。

所以在后续的发展过程中基本都采用异步非阻塞的编程模式。

简单来说,异步编程就是在执行一个指令之后不是马上得到结果,而是继续执行后面的指令,等到特定的事件触发后,才得到结果。

也正是因为这样,我们常常会说: Java 是由事件驱动的。

3. 异步实现

用 Java 构建一个应用的时候经常会遇到异步编程,不管是 Node 服务端还是 Web 前端。

那如何去进行异步编程呢?就目前的标准以及草案来看,主要有下面的几种方式:

回调

promise

Generator

await/async

3.1 回调

这种异步的方式是最基础的实现,如果你曾经写过一点的 Node, 可能经常会遇到这样的代码:


【第731期】回调地狱的今生前世@JavaScript

如此,connection.query() 是一个异步的操作,我们在调用他的时候,不会马上得到结果,而是会继续执行后面的代码。这样,如果我们需要在查到结果之后才做某些事情的话,就需要把相关的代码写在回调里面,如果涉及到多个这样的异步操作,就势必会陷入到回调地狱中去。

这种回调地狱不仅看起来很不舒服,可读性比较差;除此之外还有比较重要的一点就是对异常的捕获无法支持。

3.2 Promise

Promise 是 ES 2015 原生支持的,他把原来嵌套的回调改为了级联的方式。

一般着,我们对一个 Promise 可以这样写:


【第731期】回调地狱的今生前世@JavaScript

如果要涉及到多个异步操作的顺序执行问题,我们可以这样写:


【第731期】回调地狱的今生前世@JavaScript

也可以把函数抽离出来


【第731期】回调地狱的今生前世@JavaScript

我们只需要 return 一个 Promise 即可实现这种多个异步操作的顺序执行。

粗略来看,这是一个比较优雅的异步解决方案了,并且在 Promise 中我们也可以实现分级的 catch。

但对于之前接触过其他语言的同学来说还是比较别扭的。那能否用同步的方式来书写异步呢?

3.3 Generator

在 ES 2015 中,出现了 Generator 的语法,熟悉 python 的同学肯定对这种语法有点了解。

简单来说,Generator 可以理解为一个可以遍历的状态机,调用 next 就可以切换到下一个状态。

在 Java 中,Generator 的 function 与 函数名之间有一个 *, 函数内部使用 yield 关键词,定义不同的状态。

先看一段代码:


【第731期】回调地狱的今生前世@JavaScript

上面的这段代码是借助 TJ 的 co 实现的,依照约定,co 中 yield 后面只能跟 Thunk 或者 Promise.

co 的实现代码很短,简单来说大体是这样:


【第731期】回调地狱的今生前世@JavaScript

简单来说就是一直借助 generator 的 next 进行迭代,直到完成这个异步操作才返回。当前人家官方的 co 是 200 行代码,支持异步操作的并行:


【第731期】回调地狱的今生前世@JavaScript

但如果我们使用 co,强迫症们就会觉得这不是标准的写法,有点 hack 小子的感觉。

幸运的是,在 ES 2016 的草案中,终于提出了标准的写法。

3.4 await/async

这是在 ES 2016 中引入的新关键词,这将在语言层面彻底解决 Java 的异步回调问题,目前可以借助 babel 在生产环境中使用。使用 await/async 可以让异步的操作以同步的方式来写。

使用方法和 co 非常类似,同时也支持同步写法的异常捕获。


【第731期】回调地狱的今生前世@JavaScript

如果上述的代码完全用 Promise 实现,极有可能是下面的代码:


【第731期】回调地狱的今生前世@JavaScript

相比较来说,await/async 解决了完全使用 Promise 的一个极大痛点――不同Promise之间共享数据问题:

Promise 需要设定外层数据开始共享,这样就需要在每个then里面进行赋值,而 await/async 就不存在这样的问题,只需要以同步的方式去写就可以了。

await/async 对异常的支持也是特别好的:


【第731期】回调地狱的今生前世@JavaScript
参考文献

回调地狱 @ 奇舞团博客

ES6 Generator介绍 @ 腾讯全端 AlloyTeam 团队 Blog

使用Generator解决回调地狱 @ 腾讯全端 AlloyTeam 团队 Blog

「大概可能也许是」目前最好的 Java 异步方案 async/await @ LearnClound

关于本文

作者:@rccoder

原文:https://github.com/rccoder/blog/issues/17

每天早读,三万同行一起成长

欢迎投[email protected]

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

分页:12
转载请注明
本文标题:【第731期】回调地狱的今生前世@JavaScript
本站链接:http://www.codesec.net/view/482130.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(35)