今天有空看了一下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語(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ì)的。正確來說撕瞧,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é)啊3砺P尾 !
別急,客官漠吻,聽我細(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è)語(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力穗。
- 我感覺用起來和
co
用起來很像。 - 和generator的區(qū)別也不是十分大气嫁。
- 功能沒啥實(shí)際變化当窗,但是語(yǔ)法看起來簡(jiǎn)潔了。
- 語(yǔ)法糖寸宵。