amandakelake/blog

异步(三):async/await

amandakelake opened this issue · 0 comments

async是ES7提出的函数,被誉为目前为止JS在异步操作方面的最优解

async 函数是 Generator 的语法糖。
而await命令就是内部then命令的语法糖。
使用 关键字 async 来表示,在函数内部使用 await 来表示异步。

一、相对于Generator的改进

1、内置执行器

Generator 函数的执行必须依靠执行器,而 Aysnc 函数自带执行器,调用方式跟普通函数的调用一样

2、更好的适用性

co 模块约定,yield 命令后面只能是 Thunk 函数或 Promise对象。
而 async 函数的 await 命令后面则可以是 Promise 或者 原始类型的值(Number,string,boolean,但这时等同于同步操作)

3、返回值是 Promise

async 函数返回值是 Promise 对象,比 Generator 函数返回的 Iterator 对象方便,可以直接使用 then() 方法进行调用

二、async的使用

这一部分实在想不出要写些什么
对于会Promise和Generator的同学来说,这一部分那就是五秒钟就能解决的事

三、async的错误处理

await可以直接获取到后面Promise成功状态传递的参数,但是却捕捉不到失败状态
but,Promise的运行结果可能是reject,所以最好把await命令放在try…catch代码块中

async function foo() {
	try {
		return await dosomething()
	} catch (err) {
		console.log(err)
	}
}

当 async 函数中只要一个 await 出现 reject 状态,则后面的 await 都不会被执行。

四、async注意事项

1、await只能在async函数之中使用,只能与Promise一起使用,不适用于回调

2、Await后的异步操作,如果彼此没有依赖关系最好同时触发

async function foo() {
  let a = await request(url1);
  let b = await request(url2);
  let c = await request(url3);

  return a + b + c
}

a、b、c三者的获取没有任何联系,这时候就应该用Promise.all()并发执行

async function foo() {
  let results = await Promise.all([request(url1),request(url2),request(url3)])
  return results.reduce((total,item) => total * item)
}

五、如何使用async

毕竟是ES7的语法,目前来说还是比较新的,还是需要以下babel的支持
只需要设置 presets 为 stage-3 即可

npm install babel-preset-es2015 babel-preset-stage-3 babel-runtime babel-plugin-transform-runtime

修改.babelrc文件

"presets": ["es2015", "stage-3"],
"plugins": ["transform-runtime"]