美文网首页让前端飞Web前端之路程序员
ECMAScript7 async/await 异步解决方案

ECMAScript7 async/await 异步解决方案

作者: Nian糕 | 来源:发表于2018-06-12 16:06 被阅读52次
    Unsplash

    Async 函数作为异步解决方案的最优解,async/await 特性能让我们编写出相比回调地狱和 Promise 链式调用更直观、更容易理解的代码,Async 函数返回一个 Promise 对象,可以使用 then() 方法添加回调函数,当函数执行的时候,一旦遇到 await 就会先返回,等到异步操作完成,再接着执行函数体内后面的语句

    01 初识 async/await
    const fetch = require('node-fetch');
    async function JianShuRequest(id) {
        const url     = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
              request = await fetch(url),
              data    = await request.json(); 
        console.log(`bookname: ${data.notebooks[4].name}`);
    }
    JianShuRequest('b0c7095032f3')
    
    运行结果
    02 将 Async 函数用在 Promise 链中
    const fetch = require('node-fetch');
    async function JianShuRequest(id) {
        const url     = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
              request = await fetch(url);
        return await request.json();
    }
    JianShuRequest('b0c7095032f3').then(data => {
        console.log(`bookname: ${data.notebooks[4].name}`);
    })
    
    运行结果
    03 使用 await 进行调用
    const fetch = require('node-fetch');
    async function JianShuRequest(id) {
        const url     = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
              request = await fetch(url);
        return await request.json();
    }
    (async () => {
        const data = await JianShuRequest('b0c7095032f3');
        console.log(`bookname: ${data.notebooks[4].name}`);
    })()
    
    const fetch = require('node-fetch');
    async function JianShuRequest(id) {
        const url     = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
              request = await fetch(url);
        return await request.json();
    }
    var bookname = async () => {
        const data = await JianShuRequest('b0c7095032f3');
        console.log(`bookname: ${data.notebooks[4].name}`);
    }
    bookname()
    
    运行结果
    04 await 并行

    通过移动 await 关键词的位置实现多个 await 操作串行或者并行

    const fetch = require('node-fetch');
    async function JianShuRequest(id) {
        const url     = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
              request = await fetch(url);
        return await request.json();
    }
    var bookname = async () => {
        console.time('time');
        const data_1 = await JianShuRequest('b0c7095032f3');
        const data_2 = await JianShuRequest('b0c7095032f3');
        console.log(`bookname: ${data_1.notebooks[2].name}`);
        console.log(`bookname: ${data_2.notebooks[4].name}`);
        console.timeEnd('time');
    }
    bookname()
    
    运行结果
    const fetch = require('node-fetch');
    async function JianShuRequest(id) {
        const url     = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
              request = await fetch(url);
        return await request.json();
    }
    var bookname = async () => {
        console.time('time');
        const dataPromise_1 = JianShuRequest('b0c7095032f3');
        const dataPromise_2 = JianShuRequest('b0c7095032f3');
        const data_1 = await dataPromise_1;
        const data_2 = await dataPromise_2;
        console.log(`bookname: ${data_1.notebooks[2].name}`);
        console.log(`bookname: ${data_2.notebooks[4].name}`);
        console.timeEnd('time');
    }
    bookname()
    
    运行结果

    根据两种方式得到的数据对比,并行所运行的时间更短,其主要思路是,先触发所有的请求,得到 Promise 对象,再通过 await 等待 resolve 返回的结果

    05 使用 try catch 捕捉错误
    const fetch = require('node-fetch');
    async function JianShuRequest(id) {
        const url     = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
              request = await fetch(url);
        if(request.status != 200) {
            throw new Error(request.statusText);
        }
        return await request.json();
    }
    const showJianShuRequest = async (id) => {
        try {
            const data = await JianShuRequest(id);
            console.log(`bookname: ${data.notebooks[4].name}`);
        }catch (err) {
            console.error(err);
        }
    }
    showJianShuRequest('666666');
    
    运行结果
    06 使用 Promise.all() 实现多个异步操作的并行
    const fetch = require('node-fetch');
    async function JianShuRequest(id) {
        const url     = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
              request = await fetch(url);
        return await request.json();
    }
    const showJianShuRequest = async () => {
        const [data_1, data_2] = await Promise.all([
            JianShuRequest('b0c7095032f3'),
            JianShuRequest('b0c7095032f3'),
        ])
        console.log(`bookname_1: ${data_1.notebooks[2].name}`);
        console.log(`bookname_2: ${data_2.notebooks[4].name}`);
    }
    showJianShuRequest();
    
    运行结果
    07 在循环中正确使用 await
    const fetch    = require('node-fetch'),
          bluebird = require('bluebird');
    async function JianShuRequest(id) {
        await bluebird.delay(1000);
        const url     = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
              request = await fetch(url);
        return await request.json();
    }
    const showJianShuRequest = async () => {
        console.time('time');
        const names = ['b0c7095032f3', 'b0c7095032f3'];
        for(const name of names){
            const data = await JianShuRequest(name);
            console.log(`bookname_1: ${data.notebooks[2].name}`);
            console.log(`bookname_2: ${data.notebooks[4].name}`);
        }
        console.timeEnd('time');
    }
    showJianShuRequest();
    
    运行结果
    const fetch    = require('node-fetch'),
          bluebird = require('bluebird');
    async function JianShuRequest(id) {
        await bluebird.delay(1000);
        const url     = `https://www.jianshu.com/users/b0c7095032f3/collections_and_notebooks?slug=${id}`,
              request = await fetch(url);
        return await request.json();
    }
    const showJianShuRequest = async () => {
        console.time('time');
        const names = ['b0c7095032f3', 'b0c7095032f3'];
        const promises = names.map(x => JianShuRequest(x))
        for (const promise of promises) {
            const data = await promise;
            console.log(`bookname_1: ${data.notebooks[2].name}`);
            console.log(`bookname_2: ${data.notebooks[4].name}`);
        }
        console.timeEnd('time');
    }
    showJianShuRequest();
    
    运行结果

    参考资料
    ECMAScript 6 入门——async 函数
    玩转异步 JS :async/await 简明教程
    三分钟学会用ES7中的Async/Await进行异步编程

    本篇的内容到这里就全部结束了,源码我已经发到了 GitHub async-await 上了,有需要的同学可自行下载

    End of File

    行文过程中出现错误或不妥之处在所难免,希望大家能够给予指正,以免误导更多人,最后,如果你觉得我的文章写的还不错,希望能够点一下喜欢关注,为了我能早日成为简书优秀作者献上一发助攻吧,谢谢!^ ^

    相关文章

      网友评论

        本文标题:ECMAScript7 async/await 异步解决方案

        本文链接:https://www.haomeiwen.com/subject/lxfleftx.html