async与await 写法详解

async 与 await 可以使异步代码写法更加简洁,是在es2017引入的新特性,在最新版的nodejs及Chrome中都已经支持。

async 函数
const fetch = require('node-fetch');

// function getZhihuColumn(id) {
//     const url = `https://zhuanlan.zhihu.com/api/columns/${id}`;
//     fetch(url)
//         .then(response => response.json())
//         .then(column => {
//             console.log(`NAME: ${column.title}`);
//             console.log(`INTRO: ${column.intro}`);
//         });
// }
使用async改写,使函数更加简洁
async function getZhihuColumn(id) {
    const url = `https://zhuanlan.zhihu.com/api/columns/${id}`;
    const response = await fetch(url);
    const column = await response.json();
    console.log(`NAME: ${column.title}`);
    console.log(`INTRO: ${column.intro}`);
}

getZhihuColumn('feweekly')
将async函数用在promisechain中

// async function getZhihuColumn(id) {
//     const url = `https://zhuanlan.zhihu.com/api/columns/${id}`;
//     const response = await fetch(url);
//     const column = await response.json();
//     console.log(`NAME: ${column.title}`);
//     console.log(`INTRO: ${column.intro}`);
// }

// function getZhihuColumn(id: any): Promise<any>
async function getZhihuColumn(id) {
    const url = `https://zhuanlan.zhihu.com/api/columns/${id}`;
    const response = await fetch(url);
    return await response.json();
}

// function getZhihuColumn(id: any): Promise<any>
getZhihuColumn('feweekly')
.then(column => {
    console.log(`NAME: ${column.title}`);
    console.log(`INTRO: ${column.intro}`);
})
把任意类型的函数转换为async 函数
async 用在箭头函数

// async function getZhihuColumn(id) {
//     const url = `https://zhuanlan.zhihu.com/api/columns/${id}`;
//     const response = await fetch(url);
//     return await response.json();
// }

// 箭头函数
const getZhihuColumn = async (id) => {
    const url = `https://zhuanlan.zhihu.com/api/columns/${id}`;
    const response = await fetch(url);
    return await response.json();
}

// getZhihuColumn('feweekly')
// .then(column => {
//    console.log(`NAME: ${column.title}`);
//    console.log(`INTRO: ${column.intro}`);
//})
在全局作用域下使用async关键字是非法的 需要声明一个匿名的函数表达式
(async () => {
    const columns = await getZhihuColumn('feweekly');
    console.log(`NAME: ${column.title}`);
    console.log(`INTRO: ${column.intro}`);
})()

// 另一种用法,在类的函数中使用async
class APIClient {
    async getColumn(id) {
        const url = `https://zhuanlan.zhihu.com/api/columns/${id}`;
        const response = await fetch(url);
        return await response.json();
    }
}
(async () => {
    const client = new APIClient();
    const column = await client.getColumn('feweekly');
    console.log(`NAME: ${column.title}`);
    console.log(`INTRO: ${column.intro}`);
})()

处理async函数中的错误 的几种方式
async function getZhihuColumn(id) {
    const url = `https://zhuanlan.zhihu.com/api/columns/${id}`;
    const response = await fetch(url);
    if (response.status !== 200) {
        console.log(response.status.text)
        throw new Error(response.status.text); // 1
    }
    return await response.json();
}

const showColumnInfo = async (id) => {
    try {  //2
        const column = await getZhihuColumn(id);
        console.log(`NAME: ${column.title}`);
        console.log(`INTRO: ${column.intro}`);
    } catch (error) {
        console.log("test error")
        console.log(error);
    }
}
// showColumnInfo('feweekly2');

getZhihuColumn('feweekly1')
.then(column => {
    console.log(`NAME: ${column.title}`);
    console.log(`INTRO: ${column.intro}`);
  }).catch(err=> { // 3
    console.log("err2:" + err);
    
});
正确处理多个await操作的并行串行

添加await 的语句相当于处于一个线程中几个await串行执行,没有标记await的 并行执行。

const showColumnInfo = async () => {
    try {
    	console.time('showColumnInfo');
    	
        // const column = await getZhihuColumn('feweekly');
        // const toolingtips = await getZhihuColumn('toolingtips');
        // 串行操作改为并行
        const column2 = getZhihuColumn('feweekly');
        const toolingtips2 = getZhihuColumn('toolingtips');
        const column = await column2;
        const toolingtips = await toolingtips2;
        
        console.log(`NAME: ${column.title}`);
        console.log(`INTRO: ${column.intro}`);

        console.log(`NAME: ${toolingtips.title}`);
        console.log(`INTRO: ${toolingtips.intro}`);
        
        console.timeEnd('showColumnInfo');
    } catch (error) {
        console.log("test error")
        console.log(error);
    }
}
showColumnInfo();
使用Promise.all()让多个await操作并行
const showColumnInfo = async () => {
    try {
        console.time('showColumnInfo');

        const [column, toolingtips] = await Promise.all([
            getZhihuColumn('feweekly'), 
            getZhihuColumn('toolingtips')
        ])
        
        console.log(`NAME: ${column.title}`);
        console.log(`INTRO: ${column.intro}`);

        console.log(`NAME: ${toolingtips.title}`);
        console.log(`INTRO: ${toolingtips.intro}`);
        console.timeEnd('showColumnInfo');
    } catch (error) {
        console.log("test error")
        console.log(error);
    }
}
showColumnInfo();
结合await和任意兼容then的代码
const bluebird = require('bluebird');
async function main() {
    // await 有个隐式的调用 Promise.resolve()
    // const number = await 8088
    // // const number = await Promise.resolve(8088)
    // console.log(number);
    
    // await 可以和任何兼容promise的函数接口或者说带有then接口结合在一起使用 
    console.log('waiting...');
    await bluebird.delay(2000);// 延时
    console.log('done!');
}

main();
在for循环中使用await
const showColumnInfo2 = async () => {
    try {
        console.time('showColumnInfo');

        // const names = ['feweekly', 'toolingtips']
        // // 属于循环中的串行
        // for (const name of names) {
        //     const column = await getZhihuColumn(name)
        //     console.log(`Name: ${name}`);
        // }


        const names = ['feweekly', 'toolingtips']
        // 这里已经将函数调用执行,直接返回结果
        const promises = names.map(name => getZhihuColumn(name))
        // 属于循环中的并行,将函数结果做同步,函数调用过程做异步
        for (const promise of promises) {
            const column = await promise
            console.log(`Name: ${column.title}`);
        }

        console.timeEnd('showColumnInfo');
    } catch (error) {
        console.log("test error")
        console.log(error);
    }
}
showColumnInfo2();
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中的async和await关键字是用来实现异步编程的。它们的作用是让开发人员能够更方便地处理异步任务。async关键字可以用来修饰方法,表示该方法是一个异步方法,而await关键字用于等待异步任务的完成。 async和await的使用可以帮助我们编写更简洁、易读的异步代码。当我们在一个方法中使用了async关键字时,编译器会将该方法转换为一个状态机。这样,当遇到一个耗时的操作时,我们可以使用await关键字来等待该操作完成,而不会阻塞整个线程。当异步操作完成后,代码会继续执行。 async和await的使用需要注意一些细节。首先,异步方法必须返回一个Task对象或Task<T>对象,表示异步操作的结果。其次,在异步方法中,可以使用await关键字来等待一个异步操作的完成,但需要在方法的签名中声明async关键字。而且,await关键字只能在异步方法中使用。 在使用async和await时,还需注意一些原则。首先,尽量避免在异步方法中使用阻塞操作,以充分发挥异步编程的优势。其次,可以使用Task.WhenAll或Task.WhenAny等方法来并行处理多个异步任务。另外,可以使用ConfigureAwait方法来配置异步任务的上下文。 总之,C#中的async和await提供了一种简洁、易读的方式来处理异步任务。通过合理的使用,可以提高代码的性能和可维护性。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值