重构:从Promise到Async/Await
2018-01-25 20:26
627 查看
摘要: 夸张点说,技术的发展与历史一样,顺之者昌,逆之者亡。JS开发者们,赶紧拥抱Async/Await吧!
GitHub仓库: Fundebug/promise-asyncawait
早在半年多之前,我就在鼓吹Async/Await替代Promise的6个理由,似乎还招致了一些批评。然而,直到最近,我才真正开始进行代码重构,抛弃Promise,全面使用Async/Await。因为,Node 8终于LTS了!
这些天,我大概重构了1000行代码,最大的感觉是代码简洁了很多:
真正地用同步的方式写异步代码
不用写then及其回调函数,减少代码行数,也避免了代码嵌套
所有异步调用可以写在同一个代码块中,无需定义多余的中间变量
async函数会隐式地返回一个Promise,因此可以直接return变量,无需使用Promise.resolve进行转换
下面,我们可以通过一个非常简单的示例来体验一下Async/Await的酸爽:
由示例可知,使用Async/Await极大地简化了代码,使得代码可读性提高了非常多。
对于Async/Await替代Promise的6个理由,批评者执着于Async/Await是基于Promise实现的,因此替代这个词不准确,这就有点尴尬了。
一方面,这里替代的是异步代码的编写方式,并非完全抛弃大家心爱的Promise,地球人都知道Async/Await是基于Promise的,不用太伤心;另一方面,Promise是基于回调函数实现的,那Promise也没有替代回调函数咯?
重构代码之后,我仍然用到了Promise库bluebird。”Talk is cheap, Show me the code!”,大家不妨看看两个示例。
Fundebug是全栈JavaScript错误监控平台,支持各种前端和后端框架,可以帮助您第一时间发现BUG!*
没错,我的确使用了Promise库,readFile与Promise.map都是Promise函数。但是,在调用readFile与Promise.map函数时,使用Async/Await与使用Promise是两种不同写法,它们是相互替代的关系。
使用了await的函数定义时要加一个async,调用异步函数的时候需要加一个await,这玩意写多了也觉着烦,有时候还容易忘掉。不写async代码直接报错,不写await代码执行会出错。
既然Async/Await写着有点添乱,可不可以不写呢?我想以后应该是可以的,只要能够自动识别异步代码就行了,这应该也是未来的发展方向。至于说如何实现,那我就不知道了哎。
### 总结
JavaScript的异步编写方式,从回调函数到Promise再到Async/Await,表面上只是写法的变化,本质上则是语言层的一次次抽象,让我们可以**用更简单的方式实现同样的功能**,而程序员不需要去考虑代码是如何执行的。在我看来,这样的进步应该不会停止,有一天我们也许不用写Async/Await了!
Async/Await是这样简化JavaScript代码的
版权声明:
转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/12/13/reconstruct-from-promise-to-async-await/
GitHub仓库: Fundebug/promise-asyncawait
早在半年多之前,我就在鼓吹Async/Await替代Promise的6个理由,似乎还招致了一些批评。然而,直到最近,我才真正开始进行代码重构,抛弃Promise,全面使用Async/Await。因为,Node 8终于LTS了!
Async/Await真的比Promise好吗?
是的是的。这些天,我大概重构了1000行代码,最大的感觉是代码简洁了很多:
真正地用同步的方式写异步代码
不用写then及其回调函数,减少代码行数,也避免了代码嵌套
所有异步调用可以写在同一个代码块中,无需定义多余的中间变量
async函数会隐式地返回一个Promise,因此可以直接return变量,无需使用Promise.resolve进行转换
下面,我们可以通过一个非常简单的示例来体验一下Async/Await的酸爽:
示例1
const Promise = require("bluebird") var readFile = Promise.promisify(require("fs").readFile) // 使用Promise function usePromise() { let a readFile("a.txt", "utf8") .then(tmp => { a = tmp return readFile("b.txt", "utf8") }) .then(b => { let result = a + b console.log(result) // 输出"Hello, Fundebug!" }) } // 使用Async/Await async function useAsyncAwait() { let a = await readFile("a.txt", "utf8") let b = await readFile("b.txt", "utf8") let result = a + b console.log(result) // 输出"Hello, Fundebug!" } usePromise() useAsyncAwait()
由示例可知,使用Async/Await极大地简化了代码,使得代码可读性提高了非常多。
Async/Await真的替代了Promise?
是的是的。对于Async/Await替代Promise的6个理由,批评者执着于Async/Await是基于Promise实现的,因此替代这个词不准确,这就有点尴尬了。
一方面,这里替代的是异步代码的编写方式,并非完全抛弃大家心爱的Promise,地球人都知道Async/Await是基于Promise的,不用太伤心;另一方面,Promise是基于回调函数实现的,那Promise也没有替代回调函数咯?
重构代码之后,我仍然用到了Promise库bluebird。”Talk is cheap, Show me the code!”,大家不妨看看两个示例。
示例2:Promise.promisify
使用Promise.promisify将不支持Promise的方法Promise化,调用异步接口的时候有两种方式:const Promise = require("bluebird") var readFile = Promise.promisify(require("fs").readFile) // 使用Promise function usePromise() { readFile("b.txt", "utf8") .then(b => { console.log(b) }) } // 使用Async/Await async function useAsyncAwait() { var b = await readFile("b.txt", "utf8") console.log(b) // 输出"Fundebug!" } usePromise() useAsyncAwait()
Fundebug是全栈JavaScript错误监控平台,支持各种前端和后端框架,可以帮助您第一时间发现BUG!*
示例3:Promise.map
使用Promise.map读取多个文件的数据,调用异步接口的时候有两种方式:const Promise = require("bluebird") var readFile = Promise.promisify(require("fs").readFile) var files = ["a.txt", "b.txt"] // 使用Promise function usePromise() { Promise.map(files, file => { return readFile(file, "utf8") }) .then(results => { console.log(results) }) } // 使用Async/Await async function useAsyncAwait() { var results = await Promise.map(files, file => { return readFile(file, "utf8") }) console.log(results) } usePromise() useAsyncAwait()
没错,我的确使用了Promise库,readFile与Promise.map都是Promise函数。但是,在调用readFile与Promise.map函数时,使用Async/Await与使用Promise是两种不同写法,它们是相互替代的关系。
Async/Await有什么问题吗?
有啊有啊。使用了await的函数定义时要加一个async,调用异步函数的时候需要加一个await,这玩意写多了也觉着烦,有时候还容易忘掉。不写async代码直接报错,不写await代码执行会出错。
示例4
const Promise = require("bluebird") var readFile = Promise.promisify(require("fs").readFile) // 没有Async function withoutAsync() { let b = await readFile("b.txt", "utf8") // 报错"SyntaxError: Unexpected identifier" console.log(b) } // 没有await async function withoutAwait() { let b = readFile("b.txt", "utf8") console.log(b) // 打印"Promise..." } withoutAsync() withoutAwait()
既然Async/Await写着有点添乱,可不可以不写呢?我想以后应该是可以的,只要能够自动识别异步代码就行了,这应该也是未来的发展方向。至于说如何实现,那我就不知道了哎。
### 总结
JavaScript的异步编写方式,从回调函数到Promise再到Async/Await,表面上只是写法的变化,本质上则是语言层的一次次抽象,让我们可以**用更简单的方式实现同样的功能**,而程序员不需要去考虑代码是如何执行的。在我看来,这样的进步应该不会停止,有一天我们也许不用写Async/Await了!
参考
Async/Await替代Promise的6个理由Async/Await是这样简化JavaScript代码的
版权声明:
转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/12/13/reconstruct-from-promise-to-async-await/
相关文章推荐
- 重构:从Promise到Async/Await
- 重构:从Promise到Async/Await
- ES6总结--Promise 、Generator 、Async/Await
- sleep()在ES7中利用Promise和async/await的优雅实现
- Async/Await替代Promise的6个理由
- NodeJS-Promise、await、async异步变同步
- node Promise (async/await)
- Callback Promise Generator Async-Await 和异常处理的演进
- 【前端前沿看点】告别promise的低可读性,Async/Await替代Promise的6个理由
- Callback, Promise和Async/Await的对比
- [Typescript] Promise based delay function using async / await
- 前端面试送命题(二)-callback,promise,generator,async-await
- Callback Promise Generator Async-Await 和异常处理的演进
- Promise,Async,await简介
- Promise、Async/Await的使用
- JavaScript 的 Async\/Await 完胜 Promise 的六
- Promise,同步异步,Async/await
- Async/Await替代Promise的6个理由
- Promise和Async/Await用法整理
- 前端的异步解决方案之Promise和Await-Async