ES6 新特性之 Async

稜线沙盒
• 阅读 1571

基本概念

Async实际上是一个封装了自动化执行并返回一个Promise的Generator函数的语法糖。这句话的意思我们可以分为三个部分来解读:

  • 首先它有一个自动化执行,Generator函数是依靠不停的调用.net来依次执行的,Async有一个自动化执行的过程。
  • 第二个,它返回一个Promise,也就是说在Async函数里面我们拿到它的结果需要调用promise.then。
  • Generator函数的语法糖。

不添加自动化执行脚本的函数:

    function resolveAfter2Seconds(value) {
        return new Promise(resolve => {
            setTimeout(() => {
                resolve(value);
            },2000);
        })
    }
    
    const generator = function* () {
      const value1 = yield resolveAfter2Seconds(1);
      const value2 = yield resolveAfter2Seconds(2);
      console.log(value1);
      console.log(value2);
    };

Generator自动化执行的脚本:

    function co(generatorFunction){
        return new Promise(function(resolve, reject) {
            const generator = generatorFunction();
            function step(nextF) {
                let next;
                try {
                    next = nextF();
                } catch(e) {
                    return reject(e);
                }
                // 如果遍历已经结束了
                if(next.done) {
                    return resolve(next.value);
                }
                Promise.resolve(next.value).then(function(v) {
                    step(function() {
                        return generator.next(v);
                    });
                },function(e) {
                    step(funciton() {
                        return generator.throw(e);
                    });
                });
            }
            step(function() {
                return generator.next(undefined);
            });
        });
    }
    
    co(generator);
    /*
    (4s后)
    1
    2
    */
    
    
    const async = async function () {
      const value1 = await resolveAfter2Seconds(1);
      const value2 = await resolveAfter2Seconds(2);
      console.log(value1);
      console.log(value2);
    };
    async().then(res => {
      console.log(res);
    })
    
    /*
    (4s后)
    1
    2
    */
    
    async function asyncFunc() {};
    const asyncFunc = async function () {};
    const asyncFunc = async () => {};
    const obj = {
      async asyncFunc() {}
    }

语法

  • 首先,最重要的一点是它返回一个Promise对象,也就是说,在Async里面,在它后面我们想要得到函数的执行结果,必须使用一个.then()。

    async function asyncGun() {
        return 'Eric';
    }
    
    asyncFunc().then(value => console.log(value));
    // Eric 
  • 第二个,await遇到了一个非Promise,直接返回:

    async function asyncFunc(){
        return await 'Eric';
    }
    
    asyncFunc().then(value => console.log(value));
    // Eric
  • thenable(带有then方法的一个函数)对象等同于Promise。

    class Thenable {
        constructor(timeout) {
            this.timeout = timeout;
        }
        then(resolve, reject) {
            setTimeout{
                () => resolve('resolve'),
                this.timeout
            };
        }
    }
  • Async函数任何一个await返回reject,那么就会导致整个Async的中断执行。
    promise.all(),只有当它内部所有的子promise全部reslove时,整个promise才会resolve,只要有一个reject,那么整个promise.all就会reject,aysnc同样的原理。

注意事项

  • 尽量使用try...catch代码块,因为一旦用到了Async,显然这个场景肯定是有多个不方便操作的,这个时候为了防止中间出错,最好使用一个try...catch 的代码块,然后在catch代码块的内部加上我们的一些备用数据。
  • 非继发的await同时执行,继发就是一个接一个也就是前面一个函数的输出是后面一个函数的输入,类似于函数式编程里面的compose。
    对于继发的我们没有办法只能等待前面的操作完再去执行后续操作。

    function resolveAfter2Seconds(value){
        return new Promise(resolve => {
          setTimeout(() => {
                resolve(value);
          },2000);
        });
    };
    
    const async = async function(){
        const value1 = await resolveAfter2Seconds(1);
        const value2 = await resolveAfter2Seconds(2);
        console.log(value1);
        console.log(value2);
    };
    async().then(res => {})
    // 4s 后输出
       1
       2

    怎么样才能让两者同步执行,可以有两种办法。
    第一种,使用Promise.all()将它封装起来:

    function resolveAfter2Seconds(value){
        return new Promise(resolve => {
            setTimeout(() => {
                resolve(value);
            },2000);
        });
    }
    
    const async = async function() {
        const [value1,value2] = await Promise.all([resolveAfter2Seconds(1), resolveAfter2Seconds(2)])
        console.log(value1);
        console.log(value2);
    };
    async().then(res => {});
    // 2s后输出
       1
       2

    第二种,先执行再await,也就是把异步的一个操作赋值给一个变量:

    function resolveAfter2Seconds(value){
        return new Promise(resolve => {
            setTimeout(() => {
                resolve(value);
            },2000);
        });
    }
    
    const async = async function() {
        const vpromise1 = resolveAfter2Seconds(1);
        const vpromise2 = resolveAfter2Seconds(2);
        const value1 = await vpromise1;
        const value2 = await vpromise2;
        console.log(value1);
        console.log(value2);
    }
    async().then(res => {});
    // 2s 后输出
       1
       2
点赞
收藏
评论区
推荐文章
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
郜小超 郜小超
4年前
用 async/await 来处理异步
一级标题昨天看了一篇vue的教程,作者用async/await来发送异步请求,从服务端获取数据,代码很简洁,同时async/await已经被标准化,是时候学习一下了。先说一下async的用法,它作为一个关键字放到函数前面,用于表示函数是一个异步函数,因为async就是异步的意思,异步函数也就意味着该函数的执行不会阻塞后面代码的执行。写一个async
Souleigh ✨ Souleigh ✨
4年前
理解 Javascript 中的 Async / Await
在本文中,我们将探讨async/await,对于每个Javascript开发人员来说,是异步编程的首选工具。如果您不熟悉javascript,请不要担心,本文将帮助您async/await从头开始理解。介绍async/await是javascript中的一种模式,可使您的代码以同步方式执行,但又不影响javascript的异步行为。定义异步功能要定义一
Karen110 Karen110
4年前
盘点JavaScript中async/await知识
大家好,我是进阶学习者。一、前言Async/await是以更舒适的方式使用promise的一种特殊语法,同时它也非常易于理解和使用。二、Asyncfunction让以async这个关键字开始。它可以被放置在一个函数前面。如下所示:asyncfunctionf()return1;在函数前面的“async”这个单词表达了一个简单的
Jacquelyn38 Jacquelyn38
4年前
在前端学习道路上,容易混淆的几个知识点!
async与deferasync:可选属性。表示应该立即下载脚本,但不应妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本。只对外部脚本文件有效(写在html文件中的js代码,添加此属性无效,仍按代码加载顺序执行)。defer:可选属性。标识脚本可以延迟到文档完全被解析和显示之后再执行。只对外部脚本文件有效。script标签属性async与
Stella981 Stella981
4年前
Spring @Async使用
@EnableAsync开启@Async注解功能一、功能@Async注解标记的方法可以使该方法异步的进行调用,如果在类上使用该注解,那么这个类的所有方法都会作为异步方法进行调用注意点,Async注解是基于SpringAop进行实现的,所以在相同的一个类中,方法互相调用是不会起到异步执行的作用的,这里多说一句,任何使用springaop代理实现的
Easter79 Easter79
4年前
Spring注解@Scheduled 多线程异步执行
一、前言:Spring定时任务@Schedule的使用方式,默认是单线程同步执行的,启动过程是一个单线程同步启动过程,一旦中途被阻塞,会导致整个启动过程阻塞,其余的定时任务都不会启动。二、@Schedule注解多线程的实现:多个定时任务的执行,通过使用@Async注解来实现多线程异步调用。@Scheduled(
Stella981 Stella981
4年前
ES6——Generator
ES6新引入了Generator函数,可以通过yield关键字,把函数的执行流挂起,为改变执行流程提供了可能,从而为异步编程提供解决方案。Generator函数组成Generator有两个区分于普通函数的部分一是在function后面,函数名之前有个\;函数内部有yield表达式。
Stella981 Stella981
4年前
Async详解之一:流程控制
地址:https://github.com/caolan/async(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fcaolan%2Fasync)Async的内容分为三部分:1.流程控制:简化十种常见流程的处理2.集合处理:如何使用
你真的了解@Async吗? | 京东云技术团队
开发中会碰到一些耗时较长或者不需要立即得到执行结果的逻辑,比如消息推送、商品同步等都可以使用异步方法,这时我们可以用到@Async。但是直接使用@Async会有风险,当我们没有指定线程池时,他会默认使用其Spring自带的SimpleAsyncTaskExecutor线程池,会不断的创建线程,当并发大的时候会严重影响性能。所以可以将异步指定线程池使用