Await/Async

Async其实就是Generator函数的语法糖。

啥是语法糖?就是一种更容易让人理解,代码可读性更高的另外一种语法。

const asyncRead = async function(){
    const f1 = await readFile("/etc/fstab");
    const f2 = await readFile("etc/shells");
    console.log(f1.toString());
    console.log(f2.toString());
}

可以跟Generator函数对比:就是把(*)替换成async,将yeild换成了await,仅此而已。

不同点在于:async函数的执行,直接执行函数名  asyncRead(),就会自动执行,不需要像Generator函数那样,调用next方法才执行。

Async函数的返回值时Promise对象,而Generator函数的返回值是Iterator对象,async函数完全是可以看做是多个异步操作,包装成的一个Promise对象,而await命令只是内部then的语法糖。 

1,基本用法:

在上一张的一个图中,可以看出,promise,Generator,Async/Awati的强弱关系:

Generator < Promise < Async/Await,可以看出async/await的功能之强大。所以更得好好学习呀~~~

async function timeout(ms){
    await new Promise((resolve)=>{
        setTimeout(resolve,ms);
    })
}
async function asyncPrint(value,ms){
    await timeout(ms);
    console.log(value);
}
asyncPrint('hello',50)

上面代码指定50毫秒之后输hello world。

Async的多种使用形式:

// 函数声明
async function foo() {}

// 函数表达式
const foo = async function () {};

// 对象的方法
let obj = { async foo() {} };
obj.foo().then(...)

// Class 的方法
class Storage {
  constructor() {
    this.cachePromise = caches.open('avatars');
  }

  async getAvatar(name) {
    const cache = await this.cachePromise;
    return cache.match(`/avatars/${name}.jpg`);
  }
}

const storage = new Storage();
storage.getAvatar('jake').then(…);

// 箭头函数
const foo = async () => {};

1,await命令

正常情况下,await后面是一个promise对象,如果不是,会被转化为一个立即resolve的promise对象。

async function f(){
    await Promise.reject('error');
}
f().then(v=>console.log(`success=>${v}`))
.catch(e=>console.log(`fail=>${e}`)) 
//fail=>error

await命令后面的promise对象如果变成reject状态,reject的方法参数传入了catch的回调里面,此时 整个async函数会中断执行。

如果想要前一个异步不会影响后面的异步,可以将前一个await放在try...catch里面,这样无论这个异步操作是否成功,第二个异步都会执行。或者在前一个await的promise后面加上catch语句进行捕捉reject信息,也是可以不影响后面await的执行。

async function myFunction() {
  try {
    await somethingThatReturnsAPromise();
  } catch (err) {
    console.log(err);
  }
}

// 另一种写法

async function myFunction() {
  await somethingThatReturnsAPromise()
  .catch(function (err) {
    console.log(err);
  });
}

注意的另外一点:

如果两个方法不存在继发关系,即两个独立的异步操作,完全可以让它们同时触发。

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

let [foo,bar] = await Promise.all([getFoo(),getBar()]);

还有:await命令只能用在async函数里面,用在普通函数中会报错。

async函数的实现原理:

就是Generator函数和自动执行器,包装在一个函数里面。主要是这个自动生成器是怎么实现的?

 

posted @ 2018-05-17 17:53  tangjiao_Miya  阅读(181)  评论(0编辑  收藏  举报