async&await的一些理解

今天有空看了一下node.js v7.6.0的新特性

分析

①async函數(shù)返回什么

async function func() {
    let res = await Promise.resolve(1);
    console.log('in', res);
    return res;
}
let res = func();
console.log('out', res);

運(yùn)行之前,我以為先打印 in,再輸出 out,然而我想的并沒有什么卵用。實(shí)際上,async函數(shù)返回一個(gè)一個(gè)promise,而且還是異步的。也就是說(shuō),先輸出 out, 然后才是 in。然后我就想,如果我想要的同步,怎么辦?能不能這樣

let res = await func();

事實(shí)證明,報(bào)錯(cuò),async和await是孿生兄弟不能分開的。只能這樣

(async () => {
    let res = await func();
    console.log('out', res);
})();

感覺好麻煩的樣子,最外層還要套一個(gè)async。這樣做的后果是,啟動(dòng)的時(shí)候直接從一個(gè)函數(shù)開始,然后不斷地調(diào)用async函數(shù)。跟c語(yǔ)言的main函數(shù)一樣的意思。

②async函數(shù)什么時(shí)候返回

還是直接上代碼

async function func() {
    console.log('in-before');
    let res = await Promise.resolve(1);
    console.log('in', res);
    return res;
}

let res = func();
console.log('out', res);

第一感覺: out->in-before->in???
好像會(huì)有人這么認(rèn)為,結(jié)果呢?當(dāng)然也是不對(duì)的。正確來(lái)說(shuō),in-before->out->in
為什么會(huì)這樣呢?不是說(shuō)async是異步的嗎?怎么會(huì)先輸出 in-before 的?
對(duì)于async函數(shù)來(lái)說(shuō),當(dāng)遇到第一個(gè)await關(guān)鍵字的時(shí)候就已經(jīng)返回了,跟一般函數(shù)里面的 return 一樣。

那么問題來(lái)了,如果我有2個(gè)await呢?

async function func() {
    console.log('in-before');
    let res = await Promise.resolve(1);
    console.log('in1', res);
    let res2 = await Promise.resolve(2);
    console.log('in2', res2);
    return res2;
}

let res = func().then(console.log);
console.log('out', res);

如果說(shuō)遇到第一個(gè)await已經(jīng)返回一個(gè)promise的話,那么,最終 func().then 打印的是什么呢?答案是2,在輸出 in2后打印 2 。

所以,總結(jié)一下上面的討論。調(diào)用一個(gè)async函數(shù) func 的時(shí)候,遇到第一個(gè)await就直接返回一個(gè)promise了。只是,這個(gè)promise想要繼續(xù)往下走的話,必須要等這個(gè) func 函數(shù)執(zhí)行完之后才能使用。而且這個(gè)promise.then得到的是 func的最終返回值。結(jié)合上面最后一個(gè)代碼,應(yīng)該不難理解。

只是,我覺得有點(diǎn)不可思議,說(shuō)好的遇到第一個(gè) await 就返回了,為啥最終獲取的確實(shí)最后return返回的值呢?不科學(xué)啊!!!

別急,客官,聽我細(xì)說(shuō)。看看下面這個(gè)代碼。

function func() {
    console.log('in', 1);
    return Promise.resolve(2).then(() => {
        return 3;
    });
}

func().then(console.log);
console.log('out');

看到這里,絕大多數(shù)人應(yīng)該能知道正確答案:in->out->3

再次分析

雖然在func函數(shù)遇到了關(guān)鍵字return立刻返回一個(gè)promise,但是如果要使用這個(gè)promise,必須等到func函數(shù)里面的promise先執(zhí)行完。也就是說(shuō), func().then得到的是最后的3。

回頭一看,發(fā)現(xiàn)這兩個(gè)用法其實(shí)是一樣的。你有await,我有return,大家都是直接返回了。在我看來(lái),await/async只是一個(gè)語(yǔ)法糖而已。在遇到首個(gè)await promise的時(shí)候,實(shí)際就是return了,至于下面那些邏輯,是promise鏈里面的東西。

await Promise.resolve(1);
await Promise.resolve(2);
console.log(2)
await Promise.resolve(3);
return 4;

上面代碼和下面代碼效果一樣

return Promise.resolve(1)
        .then(() => 2)
        .then(() => {
            console.log(2)
            return Promise.resolve(3);
        })
        .then(() => 4)

好看了,簡(jiǎn)潔了。

總結(jié)

  • 這個(gè)新特性 async/await 和我想象中不太一樣哇。
  • 返回的是promise(異步),如果不想顯示使用promise,只能在調(diào)用者的外層加一個(gè)async。
  • 我感覺用起來(lái)和 co 用起來(lái)很像。
  • 和generator的區(qū)別也不是十分大。
  • 功能沒啥實(shí)際變化,但是語(yǔ)法看起來(lái)簡(jiǎn)潔了。
  • 語(yǔ)法糖。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 異步編程對(duì)JavaScript語(yǔ)言太重要。Javascript語(yǔ)言的執(zhí)行環(huán)境是“單線程”的,如果沒有異步編程,根本...
    呼呼哥閱讀 7,336評(píng)論 5 22
  • 相對(duì)于回調(diào)函數(shù)來(lái)說(shuō),Promise是一種相對(duì)優(yōu)雅的選擇。那么有沒有更好的方案呢?答案就是async/await。優(yōu)...
    松哥888閱讀 47,507評(píng)論 8 36
  • 簡(jiǎn)單介紹下這幾個(gè)的關(guān)系為方便起見 用以下代碼為例簡(jiǎn)單介紹下這幾個(gè)東西的關(guān)系, async 在函數(shù)聲明前使用asyn...
    _我和你一樣閱讀 21,273評(píng)論 1 24
  • 接著上節(jié) condition_varible ,本節(jié)主要介紹future的內(nèi)容,練習(xí)代碼地址。本文參考http:/...
    jorion閱讀 14,844評(píng)論 1 5
  • R:(原文閱讀) 選自《自控力》 I(用自己的話理解原文知識(shí)點(diǎn)) 要想提高自己的自控力,必須提高自己的意志力,提高...
    Renny_xing閱讀 191評(píng)論 1 0