对于js的async和await的理解分析
发布日期:2021-05-08 01:28:09 浏览次数:21 分类:精选文章

本文共 4060 字,大约阅读时间需要 13 分钟。

async和await的深入理解

一、async和await的概念

async函数是Generator函数的语法糖,通过将星号*替换为async,yield替换为await,使代码更加简洁易读。

  • async函数是Generator函数的语法糖
  • async函数内置执行器,调用方式与普通函数相同
  • 更好的语义,async和await比Generator的星号和yield更具有语义性
  • 更广的适用性,await可以等待Promise或原始类型值
  • 返回值是Promise对象,支持then方法
  • 二、async函数的改进

  • 内置执行器,调用方式跟普通函数一样
  • 更好的语义,async和await比Generator的星号和yield更具有语义性
  • 更广的适用性,await可以等待Promise或原始类型值
  • 返回值是Promise对象,比Generator函数返回的Iterator对象更方便
  • 流程清晰,直观,操作异步流程如同操作同步流程
  • 三、async和await的实例

    1. async函数的基本使用

    async function timeout() {
    return "hello word";
    }
    timeout(); // 返回Promise对象
    console.log("我在后面,但是我是先执行的");

    2. async函数返回的Promise特性

    async function f1() {
    return "hello world11";
    }
    f1().then(v => console.log(v));

    3. await的本质

    const test = async () => {
    let message = "hello1";
    let result = await message;
    console.log(result);
    console.log("我是hello2");
    return result;
    };
    test().then(result => {
    console.log("输出", result);
    });

    4. async函数的错误处理

    async function timeout2(flag) {
    if (flag) {
    return "hello world";
    } else {
    throw "failed";
    }
    }
    timeout2(false).catch(err => {
    console.log(err);
    });

    5. async函数的使用场景

    function doubleAfter(num) {
    return new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve(2 * num)
    }, 2000);
    });
    }
    async function test() {
    let result = await doubleAfter(30);
    console.log(result);
    }
    test();

    四、async/await的实战

    1. 需求分析

    有两个延时函数,先延时1秒,再延时2秒,再延时1秒,最后输出“完成”。

    2. 实例代码

    const setDelay = (millisecond) => {
    return new Promise((resolve, reject) => {
    if (typeof millisecond != 'number') reject(new Error('参数必须是number类型'));
    setTimeout(() => {
    resolve(`我延迟了${millisecond}毫秒后输出的`)
    }, millisecond)
    });
    };
    const setDelaySecond = (seconds) => {
    return new Promise((resolve, reject) => {
    if (typeof seconds != 'number' || seconds > 10) reject(new Error('参数必须是number类型,并且小于等于10'));
    setTimeout(() => {
    resolve(`我延迟了${seconds}秒后输出的,注意单位是秒`)
    }, seconds * 1000)
    });
    };
    (async () => {
    const result = await setDelay(1000);
    console.log(result);
    console.log(await setDelaySecond(2));
    console.log(await setDelay(1000));
    console.log('完成了');
    })();

    五、async和await的面试题总结

    1. async/await的实现原理

    async/await就是Generator的语法糖,通过将星号*替换为async,yield替换为await,使异步操作更加方便。

    2. 使用async/await需要注意的事项

  • await命令后面的Promise对象可能返回rejected状态,需要加上错误处理
  • 多个await命令后面的异步操作如果不存在继发关系,最好同时触发
  • 3. async/await的技术实现原理

    function my_co(it) {
    return new Promise((resolve, reject) => {
    function next(data) {
    try {
    var { value, done } = it.next(data);
    } catch (e) {
    return reject(e);
    }
    if (!done) {
    Promise.resolve(value).then(val => {
    next(val);
    }, reject);
    } else {
    resolve(value);
    }
    }
    next();
    });
    }
    function* test() {
    yield new Promise((resolve, reject) => {
    setTimeout(resolve, 100);
    });
    yield new Promise((resolve, reject) => {
    // throw Error(1);
    resolve(10)
    });
    yield 10;
    return 1000;
    }
    my_co(test()).then(data => {
    console.log(data); // 输出1000
    }).catch((err) => {
    console.log('err: ', err);
    });

    4. async函数的优势

  • 内置执行器,调用方式跟普通函数一样
  • 更好的语义,async和await比Generator的星号和yield更具有语义性
  • 更广的适用性,await可以等待Promise或原始类型值
  • 返回值是Promise对象,比Generator函数返回的Iterator对象更方便
  • 流程清晰,直观,操作异步流程如同操作同步流程
  • 5. async函数的错误处理

    let a3;
    async function f6() {
    try {
    await Promise.reject("error");
    } catch (err) {
    console.log(err);
    }
    a3 = await 123;
    return a3;
    }
    f6().then((v) => {
    console.log(a3);
    });

    六、async函数的使用场景

    /* 函数a内部运行了一个异步任务b()。当b()运行的时候,函数a()不会中断,而是继续执行。等到b()运行结束,可能a()早就运行结束了,b()所在的上下文环境已经消失了。如果b()或c()报错,错误堆栈将不包括a()。*/
    function b() {
    return new Promise((resolve, reject) => {
    setTimeout(resolve, 200);
    });
    }
    function c() {
    throw Error(10);
    }
    const a = () => {
    b().then(() => c());
    };
    a();
    /* 改成async函数 */
    const m = async () => {
    await b();
    c();
    };
    m();
    上一篇:运用js实现随机生成短信验证码并倒计时禁用及验证的功能
    下一篇:对于js中的this指向的深入理解

    发表评论

    最新留言

    网站不错 人气很旺了 加油
    [***.192.178.218]2025年04月13日 12时51分27秒