摘要: 夸张点说,技术的发展与历史一样,顺之者昌,逆之者亡。JS开发者们,赶紧拥抱Async/Await吧!

早在半年多之前,我就在鼓吹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了!

原文地址:
https://blog.fundebug.com/2017/12/13/reconstruct-from-promise-to-async-await/

重构:从Promise到Async/Await的更多相关文章

  1. Promise及Async/Await

      一.为什么有Async/Await? 我们都知道已经有了Promise的解决方案了,为什么还要ES7提出新的Async/Await标准呢? 答案其实也显而易见:Promise虽然跳出了异步嵌套的怪 ...

  2. 异步Promise及Async/Await最完整入门攻略

    一.为什么有Async/Await? 我们都知道已经有了Promise的解决方案了,为什么还要ES7提出新的Async/Await标准呢? 答案其实也显而易见:Promise虽然跳出了异步嵌套的怪圈, ...

  3. 异步Promise及Async/Await可能最完整入门攻略

    此文只介绍Async/Await与Promise基础知识与实际用到注意的问题,将通过很多代码实例进行说明,两个实例代码是setDelay和setDelaySecond. tips:本文系原创转自我的博 ...

  4. 20分钟带你掌握JavaScript Promise和 Async/Await

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://www.freecodecamp.org/news/learn-promise-a ...

  5. node.js异步控制流程 回调,事件,promise和async/await

    写这个问题是因为最近看到一些初学者用回调用的不亦乐乎,最后代码左调来又调去很不直观. 首先上结论:推荐使用async/await或者co/yield,其次是promise,再次是事件,回调不要使用. ...

  6. Promise, Generator, async/await的渐进理解

    作为前端开发者的伙伴们,肯定对Promise,Generator,async/await非常熟悉不过了.Promise绝对是烂记于心,而async/await却让使大伙们感觉到爽(原来异步可以这么简单 ...

  7. 异步操作之 Promise 和 Async await 用法进阶

    ES6 提供的 Promise 方法和 ES7 提供的 Async/Await 语法糖都可以更好解决多层回调问题, 详细用法可参考:https://www.cnblogs.com/cckui/p/99 ...

  8. callback vs async.js vs promise vs async / await

    需求: A.依次读取 A|B|C 三个文件,如果有失败,则立即终止. B.同时读取 A|B|C 三个文件,如果有失败,则立即终止. 一.callback 需求A: let read = functio ...

  9. Callback, Promise和Async/Await的对比

    Callback, Promise和Async/Await的对比 Callback Hell getData1(function (data1) { console.log('我得到data1了') ...

  10. “setTimeout、Promise、Async/Await 的区别”题目解析和扩展

    解答这个题目之前,先回顾下JavaScript的事件循环(Event Loop). JavaScript的事件循环 事件循环(Event Loop):同步和异步任务分别进入不同的执行"场所& ...

随机推荐

  1. Nginx原理和配置总结

    一:前言 Nginx是一款优秀的HTTP服务器和反向代理服务器,除却网上说的效率高之类的优点,个人的切身体会是Nginx配置确实简单而且还好理解,和redis差不多,比rabbitmq好理解太多了: ...

  2. apache修改最大连接数报错

    报错的内容: AH00180: WARNING: MaxRequestWorkers of 2500 exceeds ServerLimit value of 256 servers, decreas ...

  3. SpringMVC(六):@RequestMapping下使用@RequestHeader绑定请求报头的属性值、@CookieValue绑定请求中的Cookie值

    备注:我本地浏览器的报头(Request Header)信息如下: Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image ...

  4. Item Pipeline

    当Item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对Item的处理. 每个item pipeline组件(有时称之为"Item Pi ...

  5. jquery checkbox radio 标签 选中的3种方法

    张映 发表于 2013-07-16 分类目录: js/jquery 标签:checkbox, jquery, radio, 选中 jquery 很灵活,checkbox radio标签选中的方法有很多 ...

  6. 关于div包裹img,底下多出3px间隙的问题

    背景:昨天写过一个div包裹图片的html,已经reset了所有的div,但还是发现img与div底部会有3px的间距,我检查了所有的css,发现并未发现什么问题,结果度娘了一下,发现好多朋友都遇到了 ...

  7. ·c#之Thread实现暂停继续(转)

    暂停与继续实现,可以使用Thread.Suspend和Thread.Resume而这两个方法,在VS2010里提示已经过时,不建议使用,在网上查阅了一些资料,发现有个事件通知的方法很好,事件通知的大致 ...

  8. linux必知必会命令

  9. Java IO(二)

    上一节我们说到通过File访问文件,但是我们访问文件的最终目的都是访问文件中的内容,那么这个时候我们就需要使用到的一个类就是:RandomAccessFile. 此类的定义如下: public cla ...

  10. Python3玩转儿 机器学习(2)

    机器学习的基本任务 分类任务 回归任务 分类任务 手写输入数字识别 分类任务: 二分类任务 判断邮件是垃圾邮件或者不是垃圾邮件 判断发放给客户信用卡有风险或者没有风险 判断病患良性肿瘤还是恶性肿瘤 判 ...