美文网首页
async/await

async/await

作者: Gopal | 来源:发表于2018-07-23 22:17 被阅读17次

    async是什么?它有什么作用?

    ES2017标准中引入了async函数,它是Generator函数的语法糖。

    它的出现,主要是为了使异步操作变得更加的简单和直观。

    基本用法

    async函数返回的是一个Promise对象,这一点极其重要,可以使用then方法添加回调函数,当函数执行的时候,一旦遇到await就会先返回,等到异步结束之后,再接着执行函数体内之后的操作。

    async function fn() {
        // console.log(a);
        return "hello";
    }
    
    fn().then(value => { 
        console.log(value);
     }).catch((err) => {
        //  console.log('打印出错误');
         console.log(err)
     })
    

    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 () => {};
    

    语法

    async语法比较简单,难点在于错误处理机制。

    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)
    )
    // Error: 出错了
    

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

    async function getTitle(url) {
      let response = await fetch(url);
      let html = await response.text();
      return html.match(/<title>([\s\S]+)<\/title>/i)[1];
    }
    getTitle('https://tc39.github.io/ecma262/').then(console.log)
    // "ECMAScript 2017 Language Specification"
    

    函数getTitle内部有三个操作:抓取网页、取出文本、匹配页面标题。只有这三个操作全部完成,才会执行then方法里面的console.log。

    await命令
    正常情况下面,await命令后面是一个Promise对象,如果不是,会被转换成一个立即resolve的Promise对象。

    await命令后面的Promise对象如果变成reject状态,则reject的参数会被catch方法的回调函数接收到。

    async function f() {
      await Promise.reject('出错了');
    }
    
    f()
    .then(v => console.log(v))
    .catch(e => console.log(e))
    // 出错了
    

    实战

    async function timeout(ms) {
        await new Promise((resolve) => {
            setTimeout(resolve, ms);
            console.log(1);
        });
    }
    
    async function asyncPrint(value, ms) {
        await timeout(ms);
        console.log(value)
    }
    
    asyncPrint('Hello', 1000)
    
    async function fn() {
        await new Promise((resolve, reject) => {
            reject('出错了~');
        })
    }
    
    fn().then((val) => {
        console.log(val)
    }).catch((err) => {
        console.log(err)
    })
    

    相关文章

      网友评论

          本文标题:async/await

          本文链接:https://www.haomeiwen.com/subject/yhhwpftx.html