ES6 -- async 和 await 关键字

async 和 await 是 ES2016 新增的两个关键字,它们借鉴了 ES2015 中生成器在实际开发中的应用,目的是简化 Promise api 的使用,并非是替代 Promise 。

async

目的是简化在函数中对 Promise 的创建。

async 用于修饰函数(无论是函数字面量还是函数表达式),放置在函数最开始的位置,被修饰函数的返回结果一定是 Promise 对象。

async function test1() {
    console.log(1);
    return 2;
}

const pro = test1();
console.log(pro);

// 等效于
function test() {
    return new Promise((resolve, reject) => {
        console.log(1);
        resolve(2);
    })
}

const pro1 = test();
console.log(pro1);

await

await关键字必须出现在async函数中。

await 用在某个表达式之前,如果表达式是一个 Promise,则得到的是thenable中的状态数据。

async function test1() {
    console.log(1);
    return 2;
}

async function test2() {
    const result = await test1();
    console.log(result); // 2
}
test2();

等效于:

function test3() {
    return new Promise((resolve, reject) => {
        console.log(111);
        resolve(2);
    })
}

async function test4() {
    return new Promise((resolve, reject) => {
        test3().then(data => {
            const result = data;
            console.log("test3", result); // test3  2
            resolve();
        })
    })
}
test4();

例子1:

<script src="./封装ajax/ajax.js"></script>
<script>
    async function getTeacher() {
        const stus = await ajax({
            url: "./回调地狱问题/json/students.json"
        })
        let cid;
        for(let i = 0; i < stus.length; i ++) {
            if(stus[i].name === "李") {
                cid = stus[i].classId;
            }
        }

        const cls = await ajax({
            url: "./回调地狱问题/json/classes.json"
        })
        let tid;
        for(let i = 0; i < cls.length; i ++) {
            if(cls[i].id === cid) {
                tid = cls[i].teacherId;
            }
        }

        const ts = await ajax({
            url: "./回调地狱问题/json/teachers.json"
        })
        // let tid;
        for(let i = 0; i < ts.length; i ++) {
            if(ts[i].id === tid) {
                console.log(ts[i]);
            }
        }
        console.log(stus, cid, tid)
    }

    getTeacher();
    console.log(123);
</script>

例子2:

function biaobai(god) {
    return new Promise(resolve => {
        console.log(`张三向${god},发出了表白短信`);

        setTimeout(() => {
            if (Math.random() < 0.3) {
                // 同意
                resolve(true);
            } else {
                resolve(false);
            }
        }, 500)
    })
}

async function biaobaiAll() {
    const gods = ["女神1", "女神2", "女神3", "女神4"];
    for(let i = 0; i < gods.length; i ++) {
        const g = gods[i];
        // 当前循环等待的 Promise 没有 resolve,下一次循环不运行
        const result = await biaobai(g);

        if(result) {
            console.log(`${g}同意了,不用再表白了`);
            break;
        }else{
            console.log(`${g}没有同意。`);
        }
    }
}

biaobaiAll();

如果 await 的表达式不是 Promise ,则会将其使用 Promise.resolve 包装后按照规则运行。

async function test() {
    const result = await 1;
    console.log(result);
}
test();

// 等价于
function test1() {
    return new Promise((resolve, reject) => {
        Promise.resolve(3).then(data => {
            const result = data;
            console.log(result);
        })
    })
}
test1();

console.log(233);
async function getPromise() {
    if(Math.random() < 0.5) {
        return 1;
    }else{
        throw 2;
    }
}

async function test() {
    try {
        const result = await getPromise();
        console.log("正常状态",result);
    }catch (err) {
        console.log("错误状态", err);
    }
}

test();

模拟setTimeout

function delay(duration) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve();
        },duration);
    })
}

async function biaobai(god) {
    console.log(`向${god}表白`);
    await delay(500);
    // if(Math.random() < 0.3) {
    //     return true;
    // }else{
    //     return false;
    // }
    return Math.random() < 0.3;
}

async function biaobaiAll() {
    const gods = ["女神1", "女神2", "女神3", "女神4"];
    for(let i = 0; i < gods.length; i ++) {
        const g = gods[i];
        // 当前循环等待的 Promise 没有 resolve,下一次循环不运行
        const result = await biaobai(g);

        if(result) {
            console.log(`${g}同意了,不用再表白了`);
            break;
        }else{
            console.log(`${g}没有同意。`);
        }
    }
}

biaobaiAll();
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容