javascript基础学习系列五百零八:异步函数

异步函数,也称为“async/await”(语法关键字),是ES6 期约模式在ECMAScript 函数中的应用。
async/await 是ES8 规范新增的。这个特性从行为和语法上都增强了JavaScript,让以同步方式写的代码能够异步执行。下面来看一个最简单的例子,这个期约在超时之后会解决为一个值:
let p = new Promise((resolve, reject) => setTimeout(resolve, 1000, 3));
这个期约在1000 毫秒之后解决为数值3。如果程序中的其他代码要在这个值可用时访问它,则需要
写一个解决处理程序:
let p = new Promise((resolve, reject) => setTimeout(resolve, 1000, 3));
p.then((x) => console.log(x)); // 3
这其实是很不方便的,因为其他代码都必须塞到期约处理程序中。不过可以把处理程序定义为一个
函数:
function handler(x) { console.log(x); }
let p = new Promise((resolve, reject) => setTimeout(resolve, 1000, 3));
p.then(handler); // 3
这个改进其实也不大。这是因为任何需要访问这个期约所产生值的代码,都需要以处理程序的形式
来接收这个值。也就是说,代码照样还是要放到处理程序里。ES8 为此提供了async/await 关键字。
异步函数
ES8 的async/await 旨在解决利用异步结构组织代码的问题。为此,ECMAScript 对函数进行了扩展,
为其增加了两个新关键字:async 和await。

  1. async
    async 关键字用于声明异步函数。这个关键字可以用在函数声明、函数表达式、箭头函数和方法上:
    async function foo() {}
    let bar = async function() {};
    let baz = async () => {};
    class Qux {
    async qux() {}
    }
    使用async 关键字可以让函数具有异步特征,但总体上其代码仍然是同步求值的。而在参数或闭
    包方面,异步函数仍然具有普通JavaScript 函数的正常行为。正如下面的例子所示,foo()函数仍然会
    在后面的指令之前被求值:
    async function foo() {
    console.log(1);
    }
    foo();
    console.log(2);
    // 1
    // 2
    不过,异步函数如果使用return 关键字返回了值(如果没有return 则会返回undefined),这
    个值会被Promise.resolve()包装成一个期约对象。异步函数始终返回期约对象。在函数外部调用这个函数可以得到它返回的期约:
    async function foo() {
    console.log(1);
    return 3;
    }
    // 给返回的期约添加一个解决处理程序
    foo().then(console.log);
    console.log(2);
    // 1
    // 2
    // 3
    当然,直接返回一个期约对象也是一样的:
    async function foo() {
    console.log(1);
    return Promise.resolve(3);
    }
    // 给返回的期约添加一个解决处理程序
    foo().then(console.log);
    console.log(2);
    // 1
    // 2
    // 3
    异步函数的返回值期待(但实际上并不要求)一个实现thenable 接口的对象,但常规的值也可以。
    如果返回的是实现thenable 接口的对象,则这个对象可以由提供给then()的处理程序“解包”。如果
    不是,则返回值就被当作已经解决的期约。下面的代码演示了这些情况:
    // 返回一个原始值
    async function foo() {
    return ‘foo’;
    }
    foo().then(console.log);
    // foo
    // 返回一个没有实现thenable 接口的对象
    async function bar() {
    return [‘bar’];
    }
    bar().then(console.log);
    // [‘bar’]
    // 返回一个实现了thenable 接口的非期约对象
    async function baz() {
    const thenable = {
    then(callback) { callback(‘baz’); }
    };
    return thenable;
    }
    baz().then(console.log);
    // baz
    // 返回一个期约
    async function qux() {
    return Promise.resolve(‘qux’);
    }
    qux().then(console.log);
    // qux
    与在期约处理程序中一样,在异步函数中抛出错误会返回拒绝的期约:
    async function foo() {
    console.log(1);
    throw 3;
    }
    // 给返回的期约添加一个拒绝处理程序
    foo().catch(console.log);
    console.log(2);
    // 1
    // 2
    // 3
    不过,拒绝期约的错误不会被异步函数捕获:
    async function foo() {
    console.log(1);
    Promise.reject(3);
    }
    // Attach a rejected handler to the returned promise
    foo().catch(console.log);
    console.log(2);
    // 1
    // 2
    // Uncaught (in promise): 3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值