Async/Await替代Promise的理由

Async/Await简介

对于从未听说过async/await的朋友,下面是简介:

  • async/await是写异步代码的新方式,以前的方法有回调函数Promise
  • async/await是基于Promise实现的,它不能用于普通的回调函数。
  • async/await与Promise一样,是非阻塞的。
  • async/await使得异步代码看起来像同步代码,这正是它的魔力所在。

Async/Await语法

示例中,getJSON函数返回一个promise,这个promise成功resolve时会返回一个json对象。我们只是调用这个函数,打印返回的JSON对象,然后返回”done”。

使用Promise是这样的:

1 const makeRequest = () =>
2   getJSON()
3     .then(data => {
4       console.log(data)
5       return "done"
6     })
7
8 makeRequest()

使用Async/Await是这样的:

1 const makeRequest = async () => {
2   console.log(await getJSON())
3   return "done"
4 }
5
6 makeRequest()

为什么Async/Await更好?

  • 真正地用同步的方式写异步代码
  • 不用写then及其回调函数,减少代码行数,也避免了代码嵌套
  • 所有异步调用可以写在同一个代码块中,无需定义多余的中间变量
  • async函数会隐式地返回一个Promise,因此可以直接return变量,无需使用Promise.resolve进行转换
  • 用Async最大的感觉是代码简洁了很多:

下面,我们可以通过一个非常简单的示例来体验一下Async/Await的酸爽:

示例1

 1 const Promise = require("bluebird")
 2 var readFile = Promise.promisify(require("fs").readFile)
 3
 4 // 使用Promise
 5 function usePromise()
 6 {
 7     let a
 8     readFile("a.txt", "utf8")
 9         .then(tmp =>
10         {
11             a = tmp
12             return readFile("b.txt", "utf8")
13         })
14         .then(b =>
15         {
16             let result = a + b
17             console.log(result) // 输出"Hello, Fundebug!"
18         })
19
20 }
21
22 // 使用Async/Await
23 async function useAsyncAwait()
24 {
25     let a = await readFile("a.txt", "utf8")
26     let b = await readFile("b.txt", "utf8")
27     let result = a + b
28     console.log(result) // 输出"Hello, Fundebug!"
29 }
30
31 usePromise()
32 useAsyncAwait()

由示例可知,使用Async/Await极大地简化了代码,使得代码可读性提高了非常多。

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化,调用异步接口的时候有两种方式:

 1 const Promise = require("bluebird")
 2 var readFile = Promise.promisify(require("fs").readFile)
 3
 4 // 使用Promise
 5 function usePromise()
 6 {
 7     readFile("b.txt", "utf8")
 8         .then(b =>
 9         {
10             console.log(b)
11         })
12 }
13
14 // 使用Async/Await
15 async function useAsyncAwait()
16 {
17     var b = await readFile("b.txt", "utf8")
18     console.log(b) // 输出"Fundebug!"
19 }
20
21 usePromise()
22 useAsyncAwait()

示例3:Promise.map

使用Promise.map读取多个文件的数据,调用异步接口的时候有两种方式:

 1 const Promise = require("bluebird")
 2 var readFile = Promise.promisify(require("fs").readFile)
 3 var files = ["a.txt", "b.txt"]
 4
 5 // 使用Promise
 6 function usePromise()
 7 {
 8     Promise.map(files, file =>
 9         {
10             return readFile(file, "utf8")
11         })
12         .then(results =>
13         {
14             console.log(results)
15         })
16 }
17
18 // 使用Async/Await
19 async function useAsyncAwait()
20 {
21     var results = await Promise.map(files, file =>
22     {
23         return readFile(file, "utf8")
24     })
25     console.log(results)
26 }
27
28 usePromise()
29 useAsyncAwait()

没错,我的确使用了Promise库,readFile与Promise.map都是Promise函数。但是,在调用readFile与Promise.map函数时,使用Async/Await与使用Promise是两种不同写法,它们是相互替代的关系。

Async/Await有什么问题吗?

有啊有啊。

使用了await的函数定义时要加一个async,调用异步函数的时候需要加一个await,这玩意写多了也觉着烦,有时候还容易忘掉。不写async代码直接报错,不写await代码执行会出错。

示例4

 1 const Promise = require("bluebird")
 2 var readFile = Promise.promisify(require("fs").readFile)
 3
 4 // 没有Async
 5 function withoutAsync()
 6 {
 7     let b = await readFile("b.txt", "utf8") // 报错"SyntaxError: Unexpected identifier"
 8     console.log(b)
 9 }
10
11 // 没有await
12 async function withoutAwait()
13 {
14     let b = readFile("b.txt", "utf8")
15     console.log(b) // 打印"Promise..."
16 }
17
18 withoutAsync()
19 withoutAwait()

既然Async/Await写着有点添乱,可不可以不写呢?我想以后应该是可以的,只要能够自动识别异步代码就行了,这应该也是未来的发展方向。至于说如何实现,那我就不知道了哎。

总结

JavaScript的异步编写方式,从回调函数到Promise再到Async/Await,表面上只是写法的变化,本质上则是语言层的一次次抽象,让我们可以用更简单的方式实现同样的功能,而程序员不需要去考虑代码是如何执行的。在我看来,这样的进步应该不会停止,有一天我们也许不用写Async/Await了!

原文地址:https://www.cnblogs.com/shiweida/p/8763123.html

时间: 2024-07-29 23:33:16

Async/Await替代Promise的理由的相关文章

[转] Async/Await替代Promise的6个理由

Node.js 7.6已经支持async/await了,如果你还没有试过,这篇博客将告诉你为什么要用它. Async/Await简介 对于从未听说过async/await的朋友,下面是简介: async/await是写异步代码的新方式,以前的方法有回调函数和Promise. async/await是基于Promise实现的,它不能用于普通的回调函数. async/await与Promise一样,是非阻塞的. async/await使得异步代码看起来像同步代码,这正是它的魔力所在. Async/A

Async/Await替代Promise的6个理由

译者按: Node.js的异步编程方式有效提高了应用性能:然而回调地狱却让人望而生畏,Promise让我们告别回调函数,写出更优雅的异步代码:在实践过程中,却发现Promise并不完美:技术进步是无止境的,这时,我们有了Async/Await. 原文: 6 Reasons Why JavaScript’s Async/Await Blows Promises Away 译者: Fundebug 为了保证可读性,本文采用意译而非直译. Node.js 7.6已经支持async/await了,如果你

js异步回调Async/Await与Promise区别 新学习使用Async/Await

Promise,我们了解到promise是ES6为解决异步回调而生,避免出现这种回调地狱,那么为何又需要Async/Await呢?你是不是和我一样对Async/Await感兴趣以及想知道如何使用,下面一起来看看这篇文章:Async/Await替代Promise的6个理由. 什么是Async/Await? async/await是写异步代码的新方式,以前的方法有回调函数和Promise. async/await是基于Promise实现的,它不能用于普通的回调函数. async/await与Prom

JavaScript 的 Async\/Await 完胜 Promise 的六

参考:http://www.10tiao.com/html/558/201705/2650964601/1.html Node 现在从版本 7.6 开始就支持 async/await 了. 简介: Async/await 是一种编写异步代码的新方法.之前异步代码的方案是回调和 promise. Async/await 实际上是建立在 promise 的基础上.它不能与普通回调或者 node 回调一起用. Async/await 像 promise 一样,也是非阻塞的. Async/await 让

JavaScript异步编程——Async/Await vs Promise

兼容性 提醒一下各位,Node 现在从版本 7.6 开始就支持 async/await 了.而就在前几天,Node 8已经正式发布了,你可以放心地使用它. 如果你还没有试过它,这里有一堆带有示例的理由来说明为什么你应该马上采用它,并且再也不会回头. Async/await  对于那些从未听说过这个话题的人来说,如下是一个简单的介绍: Async/await 是一种编写异步代码的新方法.之前异步代码的方案是回调和 promise. Async/await 实际上是建立在 promise 的基础上.

async/await、promise 遍历

for 遍历语句 async function run() { for (let i = 0; i < 2; i++) { for (let j = 0; j < 2; j++) { await new Promise(resolve => { setTimeout(async () => { await new Promise(resolve => { setTimeout(() => { console.log(1) resolve() }, 3000) }) co

关于async/await、promise和setTimeout执行顺序

先来一道关于async/await.promise和setTimeout的执行顺序的题目: 1 async function async1() { 2 console.log('async1 start'); 3 await async2(); 4 console.log('asnyc1 end'); 5 } 6 async function async2() { 7 console.log('async2'); 8 } 9 console.log('script start'); 10 set

重构:从Promise到Async/Await

摘要: 夸张点说,技术的发展与历史一样,顺之者昌,逆之者亡.JS开发者们,赶紧拥抱Async/Await吧! GitHub仓库: Fundebug/promise-asyncawait 早在半年多之前,我就在鼓吹Async/Await替代Promise的6个理由,似乎还招致了一些批评.然而,直到最近,我才真正开始进行代码重构,抛弃Promise,全面使用Async/Await.因为,Node 8终于LTS了! Async/Await真的比Promise好吗? 是的是的. 这些天,我大概重构了10

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

写这个问题是因为最近看到一些初学者用回调用的不亦乐乎,最后代码左调来又调去很不直观. 首先上结论:推荐使用async/await或者co/yield,其次是promise,再次是事件,回调不要使用. 接下来是解析,为什么我会有这样的结论 首先是回调,理解上最简单,就是我把任务分配出去,当你执行完了我就能从你那里拿到结果执行相应的回调, 这里演示一个对setTimeout的封装,规定时间后打印相应结果并执行回调函数 并且这个函数传给回调函数的参数符合node标准,第一个为error信息,如果出错e