中文字幕在线免费看线人,丰满岳乱妇一级A片,波多野结衣无码视频,亚洲欧洲无码av

一. async 和 await 在干什么

    任意一個名稱都是有意義的,先從字面意思來理解。async 是“異步”的簡寫,而 await 可以認為是 async wait 的簡寫。所以應該很好理解 async 用于申明一個 function 是異步的,而 await 用于等待一個異步方法執(zhí)行完成。

    另外還有一個很有意思的語法規(guī)定,await 只能出現(xiàn)在 async 函數(shù)中。然后細心的朋友會產生一個疑問,如果 await 只能出現(xiàn)在 async 函數(shù)中,那這個 async 函數(shù)應該怎么調用? 

    如果需要通過 await 來調用一個 async 函數(shù),那這個調用的外面必須得再包一個 async 函數(shù),然后……進入死循環(huán),永無出頭之日……

    如果 async 函數(shù)不需要 await 來調用,那 async 到底起個啥作用?

1.1. async 起什么作用

    這個問題的關鍵在于,async 函數(shù)是怎么處理它的返回值的!

    我們當然希望它能直接通過 return 語句返回我們想要的值,但是如果真是這樣,似乎就沒 await 什么事了。所以,寫段代碼來試試,看它到底會返回什么:


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

看到輸出就恍然大悟了——輸出的是一個 Promise 對象。

c:\var\test> node --harmony_async_await .
Promise { 'hello async' }


所以,async 函數(shù)返回的是一個 Promise 對象。async 函數(shù)(包含函數(shù)語句、函數(shù)表達式、Lambda表達式)會返回一個 Promise 對象。如果在函數(shù)中 return 一個直接量,async 會把這個直接量通過 Promise.resolve() 封裝成 Promise 對象。

async 函數(shù)返回的是一個 Promise 對象,所以在最外層不能用 await 獲取其返回值的情況下,我們當然應該用原來的方式:then() 鏈來處理這個 Promise 對象,就像這樣

testAsync().then(v => {
    console.log(v);    // 輸出 hello async
});


現(xiàn)在回過頭來想下,如果 async 函數(shù)沒有返回值,又該如何?很容易想到,它會返回 Promise.resolve(undefined)。

聯(lián)想一下 Promise 的特點——無等待,所以在沒有 await 的情況下執(zhí)行 async 函數(shù),它會立即執(zhí)行,返回一個 Promise 對象,并且,絕不會阻塞后面的語句。這和普通返回 Promise 對象的函數(shù)并無二致。

那么下一個關鍵點就在于 await 關鍵字了。

1.2. await 到底在等啥

一般來說,都認為 await 是在等待一個 async 函數(shù)完成。,await 等待的是一個表達式,這個表達式的計算結果是 Promise 對象或者其它值(換句話說,就是沒有特殊限定)。

因為 async 函數(shù)返回一個 Promise 對象,所以 await 可以用于等待一個 async 函數(shù)的返回值——這也可以說是 await 在等 async 函數(shù),但要清楚,它等的實際是一個返回值。注意到 await 不僅僅用于等 Promise 對象,它可以等任意表達式的結果,所以,await 后面實際是可以接普通函數(shù)調用或者直接量的。所以下面這個示例完全可以正確運行

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();

1.3. await 等到了要等的,然后呢

await 等到了它要等的東西,一個 Promise 對象,或者其它值,然后呢?我不得不先說,await 是個運算符,用于組成表達式,await 表達式的運算結果取決于它等的東西。

如果它等到的不是一個 Promise 對象,那 await 表達式的運算結果就是它等到的東西。

如果它等到的是一個 Promise 對象,await 就忙起來了,它會阻塞后面的代碼,等著 Promise 對象 resolve,然后得到 resolve 的值,作為 await 表達式的運算結果。

二. async/await 幫我們干了啥

2.1. 作個簡單的比較

    上面已經說明了 async 會將其后的函數(shù)(函數(shù)表達式或 Lambda)的返回值封裝成一個 Promise 對象,而 await 會等待這個 Promise 完成,并將其 resolve 的結果返回出來。

    現(xiàn)在舉例,用 setTimeout 模擬耗時的異步操作,先來看看不用 async/await 會怎么寫


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();

    發(fā)現(xiàn) takeLongTime() 沒有申明為 async。實際上,takeLongTime() 本身就是返回的 Promise 對象,加不加 async 結果都一樣,如果沒明白,請回過頭再去看看上面的“async 起什么作用”。

(() => {
    let promise;
    async function test() {
        promise = new Promise(resolve => resolve(0));
        promise.mark = "hello";
        return promise;
    }

    const gotPromise = test();
    console.log(`is same object?: ${promise === gotPromise}`);  // false
    console.log(`promise.mark: ${promise.mark}`);               // hello
    console.log(`gotPromise.mark: ${gotPromise.mark}`);         // undefined
})();

又一個疑問產生了,這兩段代碼,兩種方式對異步調用的處理(實際就是對 Promise 對象的處理)差別并不明顯,甚至使用 async/await 還需要多寫一些代碼,那它的優(yōu)勢到底在哪?

2.2. async/await 的優(yōu)勢在于處理 then 鏈


單一的 Promise 鏈并不能發(fā)現(xiàn) async/await 的優(yōu)勢,但是,如果需要處理由多個 Promise 組成的 then 鏈的時候,優(yōu)勢就能體現(xiàn)出來了(很有意思,Promise 通過 then 鏈來解決多層回調的問題,現(xiàn)在又用 async/await 來進一步優(yōu)化它)。

假設一個業(yè)務,分多個步驟完成,每個步驟都是異步的,而且依賴于上一個步驟的結果。我們仍然用 setTimeout 來模擬異步操作:

/**
 * 傳入參數(shù) n,表示這個函數(shù)執(zhí)行的時間(毫秒)
 * 執(zhí)行的結果是 n + 200,這個值將用于下一步驟
 */
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);
}
現(xiàn)在用 Promise 方式來實現(xiàn)這三個步驟的處理


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");
        });
}
doIt();
// c:\var\test>node --harmony_async_await .
// step1 with 300
// step2 with 500
// step3 with 700
// result is 900
// doIt: 1507.251ms

輸出結果 result 是 step3() 的參數(shù) 700 + 200 = 900。doIt() 順序執(zhí)行了三個步驟,一共用了 300 + 500 + 700 = 1500 毫秒,和 console.time()/console.timeEnd() 計算的結果一致。

如果用 async/await 來實現(xiàn)呢,會是這樣


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


結果和之前的 Promise 實現(xiàn)是一樣的,但是這個代碼看起來是不是清晰得多,幾乎跟同步代碼一樣




點贊(0) 打賞

微信公眾賬號

微信掃一掃加關注

發(fā)表
評論
返回
頂部
红桃视频成人免费视频 | 欧美无套内射女人 | 又大又粗又硬又黄毛片 | 最近日本字幕MV免费观看在线 | 亚洲有码视频在线播放 水牛影视 | 91久久精品美女高潮 | 亚洲综合色在线视屏 | 国产脚交一区二区 | 亚洲小视频在线播放 | 91传媒免费看人口 | 好吊操免费视频视频 | 午夜成人福利黄色网 | 国产海角社区在线 | 欧美丝袜在线观看网址 | 免费无遮挡黄H网站 | 日本女优激情视频不卡在线免费观看 | 国产精东精品在线精东 | 欧美激情印度国产主播 | 色翁荡熄又大又硬又粗又视频软件 | 奇米综合超碰在线 | 午夜无码熟熟妇丰满人妻视频 | 五月天激情网婷婷 | 暧暧无码在线一区 | 陌陌影视在线观看高清完整版 | 高清无码色诱人蜜臀 | 一级特黄女人18毛片免费视频 | 欧美性受XXXX黑人猛交88 | 久久精品成人一区二区三区蜜臀 | 中文字幕在线播放av | 日韩 无码 77| 巨骚综合无毒不卡 | 国产乱300部老熟女露脸 | 国产交换精品一区二区三区免费 | HEYZO无码综合国产粉嫩AV | 天堂avav天堂 | 91精品人妻一区二区三 | 人人妻人人澡人人爽人人D 成人做爰高潮片免费看三区 | 成人视频链接国产 | 亚洲一区二区乱码 | 加勒比无码天然人妻 | 欧美精品伊人久久久 |