React 学习笔记_17(JavaScript 中的异步函数(async/await))

简介

async 异步函数是 ECMAScript 第七版(ES7)才被支援的语法,而目前还没被大部分的JavaScript Engine引入,如果需要使用需要使用babel之类的工具;而异步函数和一般的函数一样,只不过可以在此函数内使用await的语法去执行并等待非同步工作(Promise),可以告别以往冗长的callback function。

async 和 await 是什么?

sync 是“异步”的简写,而await 可以认为是async wait 的简写,注意!!await只能出现在async函数中。

async的return?

async function testAsync() {    return "hello async";}const result = testAsync();console.log(result);

输出 :
http://img2.58codes.com/2024/20124767u3qbjblBKw.png

可以看到async函数return的是一个Promise Object,如果在async function中return一个直接的变数,async会通过Promise.resolve()将它封装成Promise,若在没有await的情况下执行async函数会"立即"执行返回一个Promise Object。

await ?

一般来说await是在等待一个async函数的完成,因为async函数return一个Promise Object,所以await可以用于等待一个async的return值。注意!!await不仅用于等Promise Object它也可以接普通函数或是直接的变数。

function getSomething() {    return "something";}async function testAsync() {    return Promise.resolve("hello async");}async function test() {    const v1 = await getSomething();    const v2 = await testAsync();    console.log(v1, v2);}test();

由于await后面可以接普通的函数与直接变数,所以上面的程式是可以执行的。
结果:
http://img2.58codes.com/2024/20124767iQi9FMx4I3.png

async/await实例

以setTimeout模拟好费时间的非同步操作,先看看过去的写法:

function takeLongTime() {    return new Promise(resolve => {        setTimeout(() => resolve("long_time_value"), 1000);    });}takeLongTime().then(v => {    console.log("got", v);});

使用async/await写法 :

function takeLongTime() {    return new Promise(resolve => {        setTimeout(() => resolve("long_time_value"), 1000);    });}async function test() {    const v = await takeLongTime();    console.log(v);}test();

这两个程式都会在1秒后输出"long_time_value",注意!!由于async是return一个Promise,而function takeLongTime也是return一个Promise所以功能与async function takeLongTime()...一样。

async/await 的优势

使用async/await 写法的优势在于处理多个then,使用过去的Promise通过then来解决多层callback function会相对複杂,而使用async/await可以达到一样的效果并且比较直白,对于阅读与维护变得更为简单。

举一个例子,有一个程式中分许多个步骤,而每一个步骤都是非同步的,并且将上一个步骤地结果传给你下一个步骤当作输入参数。

function takeLongTime(n) {        return new Promise(resolve => {            setTimeout(() => resolve(n + 200), n);        });    }    function step1(n) {        console.log(`step1 with ${n}`);        return takeLongTime(n);    }    function step2(n) {        console.log(`step2 with ${n}`);        return takeLongTime(n);    }    function step3(n) {        console.log(`step3 with ${n}`);        return takeLongTime(n);    }

使用Promise写法 :

function doIt(){    console.time("doIt");    const time1 = 300;    step1(time1)        .then(time2 => step2(time2))        .then(time3 => step3(time3))        .then(result => {        console.log(`result is ${result}`);        console.timeEnd("doIt");    });};

使用async/await写法 :

    doIt = async() => {        console.time("doIt");        const time1 = 300;        const time2 = await step1(time1);        console.log("time2 = " + time2);        const time3 = await step2(time2);        console.log("time3 = " + time3);        const result = await step3(time3);        console.log(`result is ${result}`);        console.timeEnd("doIt");    };    doIt();

结果 :
http://img2.58codes.com/2024/201247676NWNVr9uXT.png
将time1传递给step1,经过300ms后会将非同步的结果(Promise.resolve)return给time2,而再将time2传入step2,经过(300+200)ms后return给time3,最后将time3传入step3中,经过(500+200)ms后return给result,所以总共耗时300 + 500 + 700 = 1500ms,使用async/await与Promise的结果一样,但程式码看起来清晰许多,方便阅读也方便维护。

参考资料 :
理解JavaScript 的async/await
JavaScript 好用的 async 异步函数!


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章