這篇文章將為大家詳細(xì)講解有關(guān)es5中yield和es6的aysnc/await有什么用,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
站在用戶的角度思考問(wèn)題,與客戶深入溝通,找到中衛(wèi)網(wǎng)站設(shè)計(jì)與中衛(wèi)網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、空間域名、虛擬主機(jī)、企業(yè)郵箱。業(yè)務(wù)覆蓋中衛(wèi)地區(qū)。
最近的業(yè)余時(shí)間在看 js 相關(guān)的書(shū), 也在極客時(shí)間上買了前端相關(guān)的專欄, 對(duì)于一個(gè)非 jser 的人來(lái)說(shuō), 時(shí)時(shí)會(huì)有一種感覺(jué): js 社區(qū)是真的激進(jìn)和浮燥, 這幫規(guī)則的制定者似乎從來(lái)也不知道克制為何物. 有很多時(shí)候固有的東西是可以處理好的, 但是偏偏喜歡人為制造一些概念和語(yǔ)法糖, 人為的建起一座又一座的高山, 似乎你沒(méi)跨過(guò)就是個(gè) "菜雞"
請(qǐng)?jiān)徫业膼憾? 看《js 語(yǔ)言精粹》的時(shí)候, 這種感覺(jué)非常的強(qiáng)烈. 作者是業(yè)內(nèi)的大牛, 還制定了 json, 但是每一章還在最開(kāi)頭引一句莎翁的話, "似乎無(wú)關(guān)緊要又暗藏哲理". 書(shū)中很多內(nèi)容要表達(dá)的意思總有一種: 明明可以將話說(shuō)成 10 分讓一個(gè)普通人都能看得明白的, 卻偏不, 只說(shuō) 6 分, 剩下的自己去悟, 有很多規(guī)則性的東西并非是靠悟, 而是靠幾句話說(shuō)清楚其本質(zhì)就豁然開(kāi)朗的.
換成以前, 會(huì)覺(jué)得這人是一座好大的高山要進(jìn)行膜拜, 這幾年雖然自己技術(shù)依然不那么好, 但是還是喜歡去思考一些內(nèi)在的東西, 更在努力一點(diǎn)一點(diǎn)把心里的權(quán)威崇拜給去掉, 再看到這些的時(shí)候, "..." 這幾個(gè)標(biāo)點(diǎn)符號(hào)很容易印在腦子里. 感覺(jué)這不只是一兩個(gè)人這樣, 極有可能是整個(gè) js 圈子都是這樣
說(shuō)回標(biāo)題上來(lái), 除了看書(shū), 看專欄, 找資料, 很久都還是沒(méi)有把 generator 和 async/await 給理解透, 于是自己試著整個(gè)梳理了一下運(yùn)行的流程
我先試著在 yield 后面不跟任何的東西, 可以直接復(fù)制到控制臺(tái)輸出
function *f0(param) { console.log('n: ' + param); yield; console.log('i'); let l = yield; console.log('l: ' + l); } let v0 = f0('p'); console.log(v0.next(1)); // 輸出 n: p 和 {value: undefined, done: false} console.log('----'); console.log(v0.next(2)); // 輸出 i 和 {value: undefined, done: false} console.log('----'); console.log(v0.next(3)); // 輸出 l: 3 和 {value: undefined, done: true} console.log('----'); console.log(v0.next(4)); // 輸出 {value: undefined, done: true} console.log('----'); console.log(v0.next(5)); // 輸出 {value: undefined, done: true}
在上面的基礎(chǔ)上給方法 return 值
function *f1() { console.log('n'); yield; console.log('i'); let l = yield; console.log('l: ' + l); return '?'; } let v1 = f1(); console.log(v1.next(1)); // 輸出 n 和 {value: undefined, done: false} console.log('----'); console.log(v1.next(11)); // 輸出 i 和 {value: undefined, done: false} console.log('----'); console.log(v1.next(111)); // 輸出 l: 111 和 {value: '?', done: true} console.log('----'); console.log(v1.next(1111)); // 輸出 {value: undefined, done: true} console.log('----'); console.log(v1.next(11111)); // 輸出 {value: undefined, done: true}
然后我試著在 yield 的后面加上內(nèi)容
function *f2(param) { console.log('0: ' + param); let f = yield 1; console.log('1: ' + f); let s = yield f + 2; console.log('2: ' + s); let t = yield (s + 3); console.log('3: ' + t); let fo = (yield s) + 4; console.log('4: ' + fo); } let v2 = f2('p'); console.log(v2.next('N')); // 輸出 0: p 和 {value: 1, done: false} console.log('----'); console.log(v2.next('I')); // 輸出 1: I 和 {value: "I2", done: false} console.log('----'); console.log(v2.next('L')); // 輸出 2: L 和 {value: "L3", done: false} console.log('----'); console.log(v2.next('S')); // 輸出 3: S 和 {value: "L", done: false} console.log('----'); console.log(v2.next('H')); // 輸出 4: H4 和 {value: undefined, done: true} console.log('----'); console.log(v2.next('I')); // 輸出 {value: undefined, done: true} console.log('----'); console.log(v2.next('T')); // 輸出 {value: undefined, done: true}
最后, 在上面的基礎(chǔ)上給方法 return 值
function *f3() { console.log('0'); let y1 = yield 1; console.log('1: ' + y1); let y2 = yield y1 + 2; console.log('2: ' + y2); let y3 = yield (y2 + 3); console.log('3: ' + y3); let y4 = (yield y3) + 4; console.log('4: ' + y4); return '??'; } let v3 = f3(); console.log(v3.next('N')); // 輸出 0 和 {value: 1, done: false} console.log('----'); console.log(v3.next('I')); // 輸出 1: I 和 {value: "I2", done: false} console.log('----'); console.log(v3.next('L')); // 輸出 2: L 和 {value: "L3", done: false} console.log('----'); console.log(v3.next('S')); // 輸出 3: S 和 {value: "S", done: false} console.log('----'); console.log(v3.next('H')); // 輸出 4: H4 和 {value: "??", done: true} console.log('----'); console.log(v3.next('I')); // 輸出 {value: undefined, done: true} console.log('----'); console.log(v3.next('T')); // 輸出 {value: undefined, done: true}
大致上就清楚 yield 的運(yùn)行邏輯了, 以上面的 f3 為例, 對(duì)照上面的輸出來(lái)看, 它其實(shí)是將一個(gè)方法分成了這樣幾段來(lái)執(zhí)行
// 下面 五行一起的豎線(|) 用一個(gè)大括號(hào)表示出來(lái)會(huì)更直觀一點(diǎn) function *f3() { // 調(diào)用第 1 次 next('N') 時(shí)運(yùn)行的代碼 console.log('0'); let y1 = yield 1; return 1; // | 封裝成 {value: 1, done: false} 返回 // | // | 這兩行等同于 let y1 = yield 1; // 調(diào)用第 2 次 next('I') 時(shí)運(yùn)行的代碼 // | let y1 = 'I'; // | console.log('1: ' + y1); return y1 + 2; // | 封裝成 {value: "I2", done: false} 返回 // | // | 這兩行等同于 let y2 = yield y1 + 2; // 調(diào)用第 3 次 next('L') 時(shí)運(yùn)行的代碼 // | let y2 = 'L'; // | console.log('2: ' + y2); return y2 + 3; // | 封裝成 {value: "L3", done: false} 返回 // | // | 這兩行等同于 let y3 = yield (y2 + 3); // 調(diào)用第 4 次 next('S') 時(shí)運(yùn)行的代碼 // | let y3 = 'S'; // | console.log('3: ' + y3); return y3; // | 封裝成 {value: "S", done: false} 返回 // | // | 這兩行等同于 let y4 = (yield y3) + 4; // 調(diào)用第 5 次 next('H') 時(shí)運(yùn)行的代碼 // | let y4 = 'H' // | console.log('4: ' + y4); return '??'; // 封裝成 {value: "??", done: true} 返回 }
再回頭想一想就知道了, 第一次運(yùn)行 next('N') 的時(shí)候, 傳進(jìn)去的 N 是會(huì)被忽略的, 因?yàn)榈谝淮?next() 傳的值沒(méi)有 yield 前面來(lái)接收. 再去看書(shū)也好, 看查到的文章也好, 第一次 next() 都是沒(méi)有傳過(guò)參數(shù)
感覺(jué) yield 就是為了迭代而生的, 迭代完全可以就用 for 啊, 但是卻繞成這樣, 也不知道這是為哪般! 就這還能新弄一個(gè) for of 玩出花來(lái), 因?yàn)槊繄?zhí)行 next() 才會(huì)執(zhí)行那一段段, 還美其名曰 "咱們終于可以異步了"
再是 es7 開(kāi)始有的這倆關(guān)鍵字, 看了一個(gè)大廠的面試題, 自己為了加深對(duì)這兩個(gè)關(guān)鍵字的理解改了一下成下面這樣
async function async1() { console.log('A'); console.log(await async2()); return 'B'; } async function async2() { console.log('C'); return 'D'; } console.log('E'); setTimeout(function() { console.log('F'); }, 0); async1().then(function(r) { console.log(r); }); new Promise(function(resolve, reject) { console.log('G'); resolve(); }).then(function() { console.log('H'); }); console.log('I');
在 chrome 73.0.3683.75 底下的輸出是:
// 這個(gè) undefined 的意思應(yīng)該主要是用來(lái)分隔宏任務(wù)的, 也就是前面的主線和任務(wù)隊(duì)列是在一起的 E A C G I D H B undefined F
在 firefox 60.5.1 底下的輸出
// 這個(gè) undefined 的意思應(yīng)該只是用來(lái)分隔主線的, 任務(wù)隊(duì)列和宏任務(wù)在一起了 E A C G I undefined H D B F
在 opera 58.0.3135.107 底下的輸出是:
// 這個(gè) undefined 應(yīng)該跟 chrome 里面是一樣的 E A C G I H D B undefined F
明顯 D H B 是比較合理的. 在 firefox 和 opera 的實(shí)現(xiàn)中明顯是有問(wèn)題的, 想像得到, 低版本一點(diǎn)的 chrome 也可能是后面的結(jié)果
還有像 var let const 這種一個(gè)簡(jiǎn)單的賦值都能玩出這么多花樣(當(dāng)然, 這可以說(shuō)是歷史遺留問(wèn)題導(dǎo)致的)
老實(shí)說(shuō), 我覺(jué)得這更多是為了: "別的語(yǔ)言有, 咱們這么前衛(wèi)的語(yǔ)言當(dāng)然應(yīng)該要有!"
...
就這么樣一門語(yǔ)言, 居然可以流行成現(xiàn)在這樣, 只能說(shuō)這個(gè)世界是真奇妙
關(guān)于es5中yield和es6的aysnc/await有什么用就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
本文標(biāo)題:es5中yield和es6的aysnc/await有什么用
當(dāng)前鏈接:http://muchs.cn/article36/gehosg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、企業(yè)建站、品牌網(wǎng)站制作、用戶體驗(yàn)、虛擬主機(jī)、
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)