成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JS中的async/await -- 異步隧道盡頭的亮光

jaysun / 1490人閱讀

摘要:結(jié)果輸出可以看出函數(shù)返回的是一個(gè)對(duì)象,如果函數(shù)中一個(gè)直接量,函數(shù)會(huì)封裝成對(duì)象返回,而如果沒(méi)有返回值時(shí),函數(shù)會(huì)返回在沒(méi)有結(jié)合時(shí),函數(shù)會(huì)立即執(zhí)行,返回一個(gè)對(duì)象。

JS中的異步操作從最初的回調(diào)函數(shù)演進(jìn)到Promise,再到Generator,都是逐步的改進(jìn),而async函數(shù)的出現(xiàn)仿佛看到了異步方案的終點(diǎn),用同步的方式寫(xiě)異步。

原文鏈接

async函數(shù)

簡(jiǎn)單解釋async函數(shù)就是Generator函數(shù)的語(yǔ)法糖。

Generator函數(shù)寫(xiě)法

let promise = function (val){
    return new Promise(function (resolve, reject){
        setTimeout(()=>{
            console.log(val);
            resolve(val);
        },1000);
    });
};

let gen = function* (){
    let p1 = yield promise("1");
    let p2 = yield promise("2");
};

let genF = gen();

async函數(shù)寫(xiě)法

let promise = function (val){
    return new Promise(function (resolve, reject){
        setTimeout(()=>{
            console.log(val);
            resolve(val);
        },1000);
    });
};

let gen = async function (){
    let p1 = await promise("1");
    let p2 = await promise("2");
};

async函數(shù)是在Generator函數(shù)上進(jìn)行的改進(jìn),語(yǔ)法上Generator函數(shù)的星號(hào)換成了async,yield換成了await。
而async也與Generator函數(shù)不同:

自帶內(nèi)置執(zhí)行器,Generator函數(shù)需要依靠執(zhí)行器,而async可以和普通函數(shù)一樣,只需要一行

相對(duì)Generator函數(shù),async和await語(yǔ)義更清楚

適用性強(qiáng),yield后只能是Thunk函數(shù)和Promise對(duì)象,而await后可以是Promise對(duì)象和原始類型的值(數(shù)值、字符串、布爾型等)

async作用

寄予async函數(shù)的期望是希望可以幫助我們解決異步操作問(wèn)題,所以需要搞清楚async函數(shù)的返回值是什么。

async function asyncAwait() {
    return "async await";
}

let a = asyncAwait();
console.log(a);

結(jié)果輸出:

Promise {: "async await"}

可以看出async函數(shù)返回的是一個(gè)Promise對(duì)象,如果函數(shù)中return一個(gè)直接量,async函數(shù)會(huì)封裝成Promise對(duì)象返回,而如果沒(méi)有返回值時(shí),async函數(shù)會(huì)返回undefined

Promise {: undefined}

在沒(méi)有結(jié)合await時(shí),async函數(shù)會(huì)立即執(zhí)行,返回一個(gè)Promise對(duì)象。

await等待

await是個(gè)運(yùn)算符,等待的結(jié)果是Promise對(duì)象或其他值,比如:

function func1() {
    return "async";
}

async function func2() {
    return Promise.resolve("await");
}

async function asyncAwait() {
    let f1 = await func1();
    let f2 = await func2();
    console.log(f1, f2);
}

asyncAwait()

結(jié)果輸出:

async await

await表達(dá)式的運(yùn)算取決于等待的結(jié)果,如果它等到的不是一個(gè)Promise對(duì)象,那運(yùn)算結(jié)果就是它等到的東西,
而如果它等到的是一個(gè)Promise對(duì)象,它會(huì)阻塞后面的代碼,等著Promise對(duì)象resolve,然后得到resolve的值,作為表達(dá)式的運(yùn)算結(jié)果。
async函數(shù)調(diào)用會(huì)封裝在Promise中,這也是await需要在async函數(shù)中使用的原因。

async/await鏈?zhǔn)教幚?/b>

對(duì)于多個(gè)異步操作中,Promise的then可以解決多層回調(diào)問(wèn)題。

function ajax(t) {
    return new Promise(resolve => {
        setTimeout(() => resolve(t + 200), t);
    });
}

function step1(t) {
    console.log(`step1 in ${t}ms`);
    return ajax(t);
}

function step2(t) {
    console.log(`step2 in ${t}ms`);
    return ajax(t);
}

function step3(t) {
    console.log(`step3 in ${t}ms`);
    return ajax(t);
}

function submit(){
    console.time("submit");
    step1(200)
        .then(time2 => step2(time2))
        .then(time3 => step3(time3))
        .then(result => {
            console.log(`result is ${result}ms`);
            console.timeEnd("submit");
        });
}

submit();

async函數(shù)實(shí)現(xiàn):

function ajax(t) {
    return new Promise(resolve => {
        setTimeout(() => resolve(t + 200), t);
    });
}

function step1(t) {
    console.log(`step1 in ${t}ms`);
    return ajax(t);
}

function step2(t) {
    console.log(`step2 in ${t}ms`);
    return ajax(t);
}

function step3(t) {
    console.log(`step3 in ${t}ms`);
    return ajax(t);
}

async function submit(){
    console.time("submit");
    const t1 = 200;
    const t2 = await step1(t1);
    const t3 = await step2(t2);
    const result = await step3(t3);
    console.log(`result is ${result}`);
    console.timeEnd("submit");
}

submit();

結(jié)果輸出:

step1 in 200ms
step2 in 400ms
step3 in 600ms
result is 800
submit: 1209.85107421875ms

而如果需求變更,每一步的參數(shù)都是之前步驟的結(jié)果后,async函數(shù)可以寫(xiě)成:

function ajax(t) {
    return new Promise(resolve => {
        setTimeout(() => resolve(t + 200), t);
    });
}

function step1(t1) {
    console.log(`step1 in ${t1}ms`);
    return ajax(t1);
}

function step2(t1, t2) {
    console.log(`step2 in ${t1}ms,${t2}ms`);
    return ajax(t1 + t2);
}

function step3(t1, t2, t3) {
    console.log(`step3 in ${t1}ms,${t2}ms,${t3}ms`);
    return ajax(t1 + t2 + t3);
}

async function submit(){
    console.time("submit");
    const t1 = 200;
    const t2 = await step1(t1);
    const t3 = await step2(t1, t2);
    const result = await step3(t1, t2, t3);
    console.log(`result is ${result}`);
    console.timeEnd("submit");
}

submit();

結(jié)果輸出:

step1 in 200ms
step2 in 200ms,400ms
step3 in 200ms,400ms,800ms
result is 1600
submit: 2210.47998046875ms
async/await注意點(diǎn)

async用來(lái)申明里面包裹的內(nèi)容可以進(jìn)行同步的方式執(zhí)行,await則是進(jìn)行執(zhí)行順序控制,每次執(zhí)行一個(gè)await,阻塞代碼執(zhí)行等待await返回值,然后再執(zhí)行之后的await。

await后面調(diào)用的函數(shù)需要返回一個(gè)promise。

await只能用在async函數(shù)之中,用在普通函數(shù)中會(huì)報(bào)錯(cuò)。

await命令后面的Promise對(duì)象,運(yùn)行結(jié)果可能是rejected,所以最好把a(bǔ)wait命令放在try...catch代碼塊中。

async/await try/catch寫(xiě)法
async function asyncAwait() {
    try {
        await promise();
    } catch (err) {
        console.log(err);
    }
}

// 另一種寫(xiě)法
async function asyncAwait() {
    await promise().catch(function (err){
        console.log(err);
    });
}
總結(jié)

async/await是ES7的重要特性之一,也是目前社區(qū)里公認(rèn)的優(yōu)秀異步解決方案,當(dāng)你深入了解原理后會(huì)發(fā)現(xiàn)仿佛看到了異步回調(diào)隧道的盡頭亮光。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/107304.html

相關(guān)文章

  • ES6 Async/Await 完爆Promise6個(gè)原因

    摘要:以往的異步方法無(wú)外乎回調(diào)函數(shù)和。當(dāng)然,對(duì)這個(gè)新特性也有一定的擔(dān)心,體現(xiàn)在他使得異步代碼變的不再明顯,我們好不容易已經(jīng)學(xué)會(huì)并習(xí)慣了使用回調(diào)函數(shù)或者來(lái)處理異步。 自從Node的7.6版本,已經(jīng)默認(rèn)支持async/await特性了。如果你還沒(méi)有使用過(guò)他,或者對(duì)他的用法不太了解,這篇文章會(huì)告訴你為什么這個(gè)特性不容錯(cuò)過(guò)。本文輔以大量實(shí)例,相信你能很輕松的看懂,并了解Javascript處理異步的...

    shevy 評(píng)論0 收藏0
  • ES6 Async/Await 完爆Promise6個(gè)原因

    摘要:以往的異步方法無(wú)外乎回調(diào)函數(shù)和。當(dāng)然,對(duì)這個(gè)新特性也有一定的擔(dān)心,體現(xiàn)在他使得異步代碼變的不再明顯,我們好不容易已經(jīng)學(xué)會(huì)并習(xí)慣了使用回調(diào)函數(shù)或者來(lái)處理異步。 自從Node的7.6版本,已經(jīng)默認(rèn)支持async/await特性了。如果你還沒(méi)有使用過(guò)他,或者對(duì)他的用法不太了解,這篇文章會(huì)告訴你為什么這個(gè)特性不容錯(cuò)過(guò)。本文輔以大量實(shí)例,相信你能很輕松的看懂,并了解Javascript處理異步的...

    W4n9Hu1 評(píng)論0 收藏0
  • Generator和Async/Await

    摘要:以往的異步方法無(wú)外乎回調(diào)函數(shù)和。出錯(cuò)了出錯(cuò)了總結(jié)接口遍歷器對(duì)象除了具有方法,還可以具有方法和方法。函數(shù)調(diào)用函數(shù),返回一個(gè)遍歷器對(duì)象,代表函數(shù)的內(nèi)部指針。 引言 接觸過(guò)Ajax請(qǐng)求的會(huì)遇到過(guò)異步調(diào)用的問(wèn)題,為了保證調(diào)用順序的正確性,一般我們會(huì)在回調(diào)函數(shù)中調(diào)用,也有用到一些新的解決方案如Promise相關(guān)的技術(shù)。 在異步編程中,還有一種常用的解決方案,它就是Generator生成器函數(shù)。顧...

    Eastboat 評(píng)論0 收藏0
  • 淺析JavaScript異步

    摘要:回調(diào)函數(shù),一般在同步情境下是最后執(zhí)行的,而在異步情境下有可能不執(zhí)行,因?yàn)槭录](méi)有被觸發(fā)或者條件不滿足。同步方式請(qǐng)求異步同步請(qǐng)求當(dāng)請(qǐng)求開(kāi)始發(fā)送時(shí),瀏覽器事件線程通知主線程,讓線程發(fā)送數(shù)據(jù)請(qǐng)求,主線程收到 一直以來(lái)都知道JavaScript是一門(mén)單線程語(yǔ)言,在筆試過(guò)程中不斷的遇到一些輸出結(jié)果的問(wèn)題,考量的是對(duì)異步編程掌握情況。一般被問(wèn)到異步的時(shí)候腦子里第一反應(yīng)就是Ajax,setTimse...

    Tangpj 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<