es5中yield和es6的aysnc/await有什么用

這篇文章將為大家詳細(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)行的流程

Generator

我先試著在 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í)行那一段段, 還美其名曰 "咱們終于可以異步了"

async/await

再是 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)

h5響應(yīng)式網(wǎng)站建設(shè)