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,而且還是異步的。也就是說,先輸出 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語言的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ì)的。正確來說,in-before->out->in。
為什么會(huì)這樣呢?不是說async是異步的嗎?怎么會(huì)先輸出 in-before 的?
對(duì)于async函數(shù)來說,當(dāng)遇到第一個(gè)await關(guān)鍵字的時(shí)候就已經(jīng)返回了,跟一般函數(shù)里面的 return 一樣。

那么問題來了,如果我有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);

如果說遇到第一個(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)不可思議,說好的遇到第一個(gè) await 就返回了,為啥最終獲取的確實(shí)最后return返回的值呢?不科學(xué)?。。?!

別急,客官,聽我細(xì)說。看看下面這個(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í)行完。也就是說, func().then得到的是最后的3。

回頭一看,發(fā)現(xiàn)這兩個(gè)用法其實(shí)是一樣的。你有await,我有return,大家都是直接返回了。在我看來,await/async只是一個(gè)語法糖而已。在遇到首個(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。
  • 我感覺用起來和 co 用起來很像。
  • 和generator的區(qū)別也不是十分大。
  • 功能沒啥實(shí)際變化,但是語法看起來簡(jiǎn)潔了。
  • 語法糖。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容