首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >async函数

async函数

作者头像
用户3258338
发布2019-08-20 14:56:12
7890
发布2019-08-20 14:56:12
举报

爱是天时地利的迷信---《原来你也在这里》

嗨,宝宝们,emmm…… 我一说“宝宝们”这三个字就想起一个男生……

1.async的含义

async函数其实是Geneator函数的语法糖。

async函数对Generator函数的改进:

(1)内置执行器

Generator函数的执行必须靠执行器,所以才有co模块,而async函数自带执行器。

(2)更好的语义

async和await,相比于*和yield语义更清楚。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。

(3)更广的适用性

co模块预定,yield命令后面只能是Thunk函数或Promise对象。而async函数的await命令后面可以是Promise对象和原始类型的值(数值、字符串和布尔值,这时候自动转成立即resolve的Promise对象)

(4)返回值是Promise

async函数的返回值是Promise对象,可以用then方法指定下一步的操作。async函数可以看做多个异步操作,包装成一个Promise对象,await命令就是内部then命令的语法糖。

2.async用法

async函数返回一个Promise对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体后面的语句。

例:

async function getStockPriceByName(name){
  const symbol = await getStockSymbol(name);
  const stockPrice = await getStockPricd(symbol);
  return stockPrice;
}
getStockPriceByName('goog').then(function(res){
  console.log(res);
})

函数前面的async关键字,表明该函数内部有异步操作。调用该函数时,会立即返回一个Promise对象。

2.async语法

返回Promise对象

async函数返回一个Promise对象。

async函数内部return语句返回的值,会成为then方法回调函数的参数。

async function f(){
  return 'hello world';
}
f().then(v=>console.log(v))
// "hello world;"

async函数内部抛出错误,会导致返回的Promise对象变成reject状态,抛出的错误对象会被catch方法回调函数接收到。

async function f(){
  throw new Error('出错了');
}
f().then(
  v => console.log(v),
  e => console.log(e)
)

Promise对象的状态变化

async函数返回的Promise对象,必须等到内部所有的await命令后面的Promise对象执行完,才会发生状态变化,除非遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行执行then方法指定的回调函数。

await命令

正常情况下,await命令后面是一个Promise对象,返回该对象的结果。如果不是Promise对象,就直接返回对应的值。

另外,await命令后面是一个thenable对象(定义了then方法的对象),那么await会将其等同于Promise对象。

任何一个await语句后面的Promise对象变为reject状态,那么整个async函数都会中断执行。

async function f(){
  await Promise.reject('出错了');
  await Promise.resolve('hello world');
}

上面代码中,第二个await语句是不会执行的,因为第一个await语句变成了reject。

可是如果我想要第二个await语句执行呢?

async function f(){
  try{
  await Promise.reject('出错了');

  }catch{}
  return await Promise.resolve('hello world');
}

还可以

async function f(){
  await Promise.reject('出错了')
    .catch(e => console.log(e))
  return await Promise.resolve('hello world');
}

错误处理

await后面的异步操作出错,等于async函数返回的Promise对象被reject。

注意事项:

1.await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中。

async function fun(){
  try{
    await returnPromise();
  }catch(err){
    console.log(err)
  }
}
// 或者
async function fun1(){
  await returnPromise()
  .catch(function(err){
    console.log(err)
  })
}

2.多个await命令后面的异步操作,如果不存在继发关系,最好让他们同时触发

let foo = await getFoo();
let bar = await getBar();

getFoo和getBar是两个独立的异步操作,被写成激发关系比较耗时,所以可以让他们同时触发,方法如下:

let [foo, bar] = await Promise.all([getFoo(),getBar()]);
// 或者
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;

3. await命令只能用在async函数之中,若用在普通函数中会报错。

4. async函数可以保留运行堆栈。

const a =()=>{
  b().then(()=>c{});
}

以上,当b运行时,a不会中断,而是继续执行。等到b()运行结束,可能a早就运行结束,b所在的上下文环境已经消失。如果b或c报错,错误堆栈将不包括a。

const a = async()=>{
  await b();
  c();
}

b运行的时候,a暂停运行,上下文环境都保存着,一旦b或c报错,错误堆栈将包括a。

愿我们有能力不向生活缴械投降---Lin

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 女程序员的日常 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档