Open brunoyang opened 8 years ago
:+1:
:+1:
async的本质是generator,babel是把async编译成generator的
赞!不知道async能不能用在成员函数上?
class AsyncTest {
async foo() {...}
}
let asyncTest = new AsyncTest();
asyncTest.foo();
`
@puncha 👍 多谢提醒,已在结尾补充
写的很不错,现在用阿里的egg2 可以用原生async很爽
据说,async 将在2016年 Q2,也就是今年的 4~6 月份于 V8 上推出,到那时,我们就可以欢快地写上『同步代码』啦!所以,本文的目的就是教大家如何使用 async。
配置 webpack + babel 使用 async
首先,安装
babel-core
和babel-loader
,这两项分别是 babel 的核心和 babel 能够在 webpack 中运行的保障。接着,安装
babel-preset-stage-3
插件,就可以直接使用 async 了。若你希望你的代码可以在浏览器,或是 node v4 以下的环境上运行,就需要加上
babel-preset-es2015
,因为 babel 转码 async 的原理是将其转为 generator,低版本浏览器若要使用 generator,还需要再转成 es5 的代码。其外,若要在 react 中使用,需另加babel-preset-react
。附一份 webpack.config.js 的 loader部分
正文
我们先来写一个最简单的 async 函数
done!
只需要在 function 前面加上 async 关键字,以及在被调用的函数前面加上 await 关键字,就是这么简单。 来讲讲需要注意的几点
1.首先,请谨记,async的基础是 promise,我们可以试着改写
githubPage
这个函数对比两个版本的
githubPage
函数,就能发现,await 相当于是调用了 then 方法,并拿到返回值(当然这只是打个比方,实际上 then 函数是用来注册回调的)。2.await 关键字不允许出现在普通函数中。
map((x) => await x * x)
,类似这样的代码是会报错的。map(async (x) => await x * x)
,这样的代码不会报错,但是不符合我们的预期,其中的 await 不是顺序执行而是并行地执行,至于原因,请看这里。没有办法,目前看来,只能在 for 循环中使用async 函数的返回值是一个 promise,也就是说,我们可以写这样的代码:
若 await 后的函数 reject 了,或是抛出了一个错,上面的代码是没有办法处理的。当然应对方法也很简单,就是把业务代码都包裹在 try/catch 中,在 catch 中对错误进行统一处理。
上面的代码都是顺序执行,那怎么让两个 await 同时执行呢
很简单吧,不过,上面的写法已经被废弃了,得用下面这个写法:
虽然也很好理解,但不得不吐槽这样写实在是太丑了。 当然,有 Promise.all 自然也可以用 Promise.race
async 也可以在 class 中使用:
若是像上面这样直接调用,并不会得到预期的结果,因为这相当于是不加 await 调用 async 函数。我们需要将函数调用包装一下
(快去抢注 co-async):