zoukankan      html  css  js  c++  java
  • 理解ES7中的async/await

    理解ES7中的async/await

       优势是:就是解决多层异步回调的嵌套

     从字面上理解 async/await, async是 "异步"的含义,await可以认为是 async wait的简写,因此可以理解 async 用于声明一个function是异步的,而await用于等待一个异步方法执行完成返回的值(返回值可以是一个Promise对象或普通返回的值)。
    注意:await 只能出现在 async函数中。

    1-1 async的作用?
    首先来理解async函数是怎么处理返回值的,我们以前写代码都是通过return语句返回我们想要的值,但是async与return有什么区别呢? 下面我们看如下代码:

    async function testAsync() {
      return 'hello world';
    }
    const result = testAsync();
    console.log(result);  // 打印出来看到 返回一个promise对象

    如上代码,我们输出的是一个Promise对象。因此 async返回的是一个Promise对象,因此我们可以使用 then()链来处理这个Promise对象。像如下代码:

    async function testAsync() {
      return 'hello world';
    }
    const result = testAsync();
    result.then(v => {
      console.log(v);  // 输出 hello world
    });

    但是如果 async函数没有返回值的话,那么就会返回 undefined; 如下代码:

    async function testAsync() {
      return;
    }
    const result = testAsync();
    result.then(v => {
      console.log(v);  // 输出 undefined
    });

    1-2 await的作用?
    从语义上说,await是在等待一个async函数完成的,async函数返回的是一个Promise对象,await等待的是一个表达式,这个表达式的计算结果是Promise对象或其他值。
    async函数返回一个Promise对象,await作用是用于等待一个async函数的返回值。
    await函数后面可以接普通函数调用或直接量,请看如下代码:

    function getSomething() {
      return 'something';
    }
    
    async function testAsync() {
      return Promise.resolve('hello');
    }
    
    async function test () {
      const v1 = await getSomething();
      const v2 = await testAsync();
      console.log(v1);  // something
      console.log(v2);  // hello
    }
    test();

    注意:await 是等待async函数返回的Promise对象或其他值,await是一个运算符,用于组成表达式, 如果等待的是一个Promise对象,await会阻塞后面的代码(async调用不会造成堵塞,它内部所有的堵塞
    都被封装在一个Promise对象中异步执行),等待Promise对象的resolve,然后得到resolve的值,作为await表达式的运输结果。

    1-3 async/await 的一起使用的作用及优势在哪?
    我们先不用 async/await, 来看看使用setTimeout模拟异步操作如下代码:

    var test = function(time) {
      return new Promise((resolve, reject) => {
        setTimeout(function(){
          resolve('hello world');
        }, time)
      });
    };
    
    test(1000).then((v) => {
      console.log(v);
    });

    如果改用 async/await 代码如下:

    var testAsync = function(time) {
      return new Promise((resolve, reject) => {
        setTimeout(function(){
          resolve('hello world');
        }, time)
      });
    };
    
    async function test(time) {
      const v = await testAsync(time);
      console.log(v); // hello world
    }
    test(1000);

    看上面的代码,反而会觉得 使用 async/await 代码变得多一点,复杂一点,但是结果貌似都一样,那么使用 async/await的优势在哪?

    1-4 async/await的优势在于处理then链

    单一的Promise链貌似不能发现 async/await的优势,但是如果需要处理多个Promise组成的then链的时候,优势可以看出来,因为Promise是通过then链来解决多层回调的问题,现在我们又可以使用
    async/await来进一步优化,他们的优点就是解决多层异步回调的嵌套。

    假设我们现在有一个需求是,分多个步骤完成,每个步骤都是异步的,并且后面的异步都需要依赖于上一个异步回调返回的数据,进行往下传递。我们先用 setTimeout来模拟异步操作。

    function useTimeout (t) {
      return new Promise((resolve, reject) => {
        setTimeout(()=> {
          resolve(t+100)
        }, t);
      });
    }
    
    function step1(t) {
      console.log(`step1 with ${t}`); // step1 with 300
      return useTimeout(t);
    }
    
    function step2(t) {
      console.log(`step2 with ${t}`); // step2 with 400
      return useTimeout(t);
    }
    
    function step3(t) {
      console.log(`step3 with ${t}`); // step3 with 500
      return useTimeout(t);
    }
    
    function test() {
      const time1 = 300;
      step1(time1)
        .then(time2 => step2(time2))
        .then(time3 => step3(time3))
        .then(res => {
          console.log(`result is ${res}`);  // result is 600
        })
    } 
    test();

    如果我们使用 async/await来实现,代码变为如下:

    function useTimeout (t) {
      return new Promise((resolve, reject) => {
        setTimeout(()=> {
          resolve(t+100)
        }, t);
      });
    }
    
    function step1(t) {
      console.log(`step1 with ${t}`); // step1 with 300
      return useTimeout(t);
    }
    
    function step2(t) {
      console.log(`step2 with ${t}`); // step2 with 400
      return useTimeout(t);
    }
    
    function step3(t) {
      console.log(`step3 with ${t}`); // step3 with 500
      return useTimeout(t);
    }
    
    async function test() {
      const time1 = 300;
      const time2 = await step1(time1);
      const time3 = await step2(time2);
      const result = await step3(time3);
      console.log(`result is ${result}`);
    } 
    test();

    上面我们可以看到 使用async/await 代码看起来都是同步的,等第一步完成后,再执行第二步,依次类推..... 并且不需要更多的回调函数嵌套。

    下面我们再来看下我们之前讲的,后面的步骤需要上一个步骤的结果传递进去,使用async/await的优势可能更明显。
    如下代码:

    function useTimeout (t) {
      return new Promise((resolve, reject) => {
        setTimeout(()=> {
          resolve(t+100)
        }, t);
      });
    }
    
    function step1(t1) {
      console.log(`step1 with ${t1}`); // step1 with 300
      return useTimeout(t1);
    }
    
    function step2(t1, t2) {
      console.log(`step2 with ${t1} and ${t2}`); // step2 with 300 and 400
      return useTimeout(t1+t2);
    }
    
    function step3(t1, t2, t3) {
      console.log(`step3 with ${t1} and ${t2} and ${t3}`); // step3 with 300 and 400 and 800
      return useTimeout(t1+t2+t3);
    }
    
    async function test() {
      const time1 = 300;
      const time2 = await step1(time1);
      const time3 = await step2(time1, time2);
      const result = await step3(time1, time2, time3);
      console.log(`result is ${result}`);  // result is 1600
    } 
    test();

    1-5 捕捉错误
    我们可以使用 try catch 来捕获错误,如下代码:

    var sleep = function (time) {
      return new Promise((resolve, reject) => {
        setTimeout(function() {
          // 出错了, 返回 error
          reject('error');
        }, time);
      })
    };
    
    var start = async function() {
      try {
        console.log('start');
        await sleep(3000); // 返回一个错误
        // 下面代码不会被执行
        console.log('end');
      } catch (err) {
        console.log(err); // 捕捉错误 error 
      }
    };
    
    start();
  • 相关阅读:
    整合SSH遇到的问题
    学习动态代理实现业务层的事务控制遇到的问题
    docker局域网独立IP外网访问配置
    第23次CSP-D题解法
    Nordic Bluetooth 切换到DFU Mode
    MySQL事务、锁和MVCC
    深拷贝和浅拷贝的区别是什么?
    python是如何进行内存管理的
    数据库的事务
    斐波那契数列
  • 原文地址:https://www.cnblogs.com/tugenhua0707/p/7351111.html
Copyright © 2011-2022 走看看