<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
        當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

        深入理解js 中async 函數(shù)的含義和用法

        來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 22:14:48
        文檔

        深入理解js 中async 函數(shù)的含義和用法

        深入理解js 中async 函數(shù)的含義和用法:一、終極解決 異步操作是 JavaScript 編程的麻煩事,麻煩到一直有人提出各種各樣的方案,試圖解決這個(gè)問(wèn)題。 從最早的回調(diào)函數(shù),到 Promise 對(duì)象,再到 Generator 函數(shù),每次都有所改進(jìn),但又讓人覺(jué)得不徹底。它們都有額外的復(fù)雜性,都需要理解抽象的底層運(yùn)行
        推薦度:
        導(dǎo)讀深入理解js 中async 函數(shù)的含義和用法:一、終極解決 異步操作是 JavaScript 編程的麻煩事,麻煩到一直有人提出各種各樣的方案,試圖解決這個(gè)問(wèn)題。 從最早的回調(diào)函數(shù),到 Promise 對(duì)象,再到 Generator 函數(shù),每次都有所改進(jìn),但又讓人覺(jué)得不徹底。它們都有額外的復(fù)雜性,都需要理解抽象的底層運(yùn)行

        一、終極解決

        異步操作是 JavaScript 編程的麻煩事,麻煩到一直有人提出各種各樣的方案,試圖解決這個(gè)問(wèn)題。

        從最早的回調(diào)函數(shù),到 Promise 對(duì)象,再到 Generator 函數(shù),每次都有所改進(jìn),但又讓人覺(jué)得不徹底。它們都有額外的復(fù)雜性,都需要理解抽象的底層運(yùn)行機(jī)制。

        異步I/O不就是讀取一個(gè)文件嗎,干嘛要搞得這么復(fù)雜?異步編程的最高境界,就是根本不用關(guān)心它是不是異步。

        async 函數(shù)就是隧道盡頭的亮光,很多人認(rèn)為它是異步操作的終極解決方案。

        二、async 函數(shù)是什么?

        一句話,async 函數(shù)就是 Generator 函數(shù)的語(yǔ)法糖。

        前文有一個(gè) Generator 函數(shù),依次讀取兩個(gè)文件。

        var fs = require('fs');
        var readFile = function (fileName){
         return new Promise(function (resolve, reject){
         fs.readFile(fileName, function(error, data){
         if (error) reject(error);
         resolve(data);
         });
         });
        };
        var gen = function* (){
         var f1 = yield readFile('/etc/fstab');
         var f2 = yield readFile('/etc/shells');
         console.log(f1.toString());
         console.log(f2.toString());
        };

        寫成 async 函數(shù),就是下面這樣。

        var asyncReadFile = async function (){
         var f1 = await readFile('/etc/fstab');
         var f2 = await readFile('/etc/shells');
         console.log(f1.toString());
         console.log(f2.toString());
        };

        一比較就會(huì)發(fā)現(xiàn),async 函數(shù)就是將 Generator 函數(shù)的星號(hào)(*)替換成 async,將 yield 替換成 await,僅此而已。

        三、async 函數(shù)的優(yōu)點(diǎn)

        async 函數(shù)對(duì) Generator 函數(shù)的改進(jìn),體現(xiàn)在以下三點(diǎn)。

        (1)內(nèi)置執(zhí)行器。 Generator 函數(shù)的執(zhí)行必須靠執(zhí)行器,所以才有了 co 函數(shù)庫(kù),而 async 函數(shù)自帶執(zhí)行器。也就是說(shuō),async 函數(shù)的執(zhí)行,與普通函數(shù)一模一樣,只要一行。

        var result = asyncReadFile();

        (2)更好的語(yǔ)義。 async 和 await,比起星號(hào)和 yield,語(yǔ)義更清楚了。async 表示函數(shù)里有異步操作,await 表示緊跟在后面的表達(dá)式需要等待結(jié)果。

        (3)更廣的適用性。 co 函數(shù)庫(kù)約定,yield 命令后面只能是 Thunk 函數(shù)或 Promise 對(duì)象,而 async 函數(shù)的 await 命令后面,可以跟 Promise 對(duì)象和原始類型的值(數(shù)值、字符串和布爾值,但這時(shí)等同于同步操作)。

        四、async 函數(shù)的實(shí)現(xiàn)

        async 函數(shù)的實(shí)現(xiàn),就是將 Generator 函數(shù)和自動(dòng)執(zhí)行器,包裝在一個(gè)函數(shù)里。

        async function fn(args){
         // ...
        }
        // 等同于
        function fn(args){ 
         return spawn(function*() {
         // ...
         }); 
        }

        所有的 async 函數(shù)都可以寫成上面的第二種形式,其中的 spawn 函數(shù)就是自動(dòng)執(zhí)行器。

        下面給出 spawn 函數(shù)的實(shí)現(xiàn),基本就是前文自動(dòng)執(zhí)行器的翻版。

        function spawn(genF) {
         return new Promise(function(resolve, reject) {
         var gen = genF();
         function step(nextF) {
         try {
         var next = nextF();
         } catch(e) {
         return reject(e); 
         }
         if(next.done) {
         return resolve(next.value);
         } 
         Promise.resolve(next.value).then(function(v) {
         step(function() { return gen.next(v); }); 
         }, function(e) {
         step(function() { return gen.throw(e); });
         });
         }
         step(function() { return gen.next(undefined); });
         });
        }

        async 函數(shù)是非常新的語(yǔ)法功能,新到都不屬于 ES6,而是屬于 ES7。目前,它仍處于提案階段,但是轉(zhuǎn)碼器 Babel 和 regenerator 都已經(jīng)支持,轉(zhuǎn)碼后就能使用。

        五、async 函數(shù)的用法

        同 Generator 函數(shù)一樣,async 函數(shù)返回一個(gè) Promise 對(duì)象,可以使用 then 方法添加回調(diào)函數(shù)。當(dāng)函數(shù)執(zhí)行的時(shí)候,一旦遇到 await 就會(huì)先返回,等到觸發(fā)的異步操作完成,再接著執(zhí)行函數(shù)體內(nèi)后面的語(yǔ)句。

        下面是一個(gè)例子。

        async function getStockPriceByName(name) {
         var symbol = await getStockSymbol(name);
         var stockPrice = await getStockPrice(symbol);
         return stockPrice;
        }
        getStockPriceByName('goog').then(function (result){
         console.log(result);
        });

        上面代碼是一個(gè)獲取股票報(bào)價(jià)的函數(shù),函數(shù)前面的async關(guān)鍵字,表明該函數(shù)內(nèi)部有異步操作。調(diào)用該函數(shù)時(shí),會(huì)立即返回一個(gè)Promise對(duì)象。

        下面的例子,指定多少毫秒后輸出一個(gè)值。

        function timeout(ms) {
         return new Promise((resolve) => {
         setTimeout(resolve, ms);
         });
        }
        async function asyncPrint(value, ms) {
         await timeout(ms);
         console.log(value)
        }
        asyncPrint('hello world', 50);

        上面代碼指定50毫秒以后,輸出"hello world"。

        六、注意點(diǎn)

        await 命令后面的 Promise 對(duì)象,運(yùn)行結(jié)果可能是 rejected,所以最好把 await 命令放在 try...catch 代碼塊中。

        async function myFunction() {
         try {
         await somethingThatReturnsAPromise();
         } catch (err) {
         console.log(err);
         }
        }
        // 另一種寫法
        async function myFunction() {
         await somethingThatReturnsAPromise().catch(function (err){
         console.log(err);
         });
        }

        await 命令只能用在 async 函數(shù)之中,如果用在普通函數(shù),就會(huì)報(bào)錯(cuò)。

        async function dbFuc(db) {
         let docs = [{}, {}, {}];
         // 報(bào)錯(cuò)
         docs.forEach(function (doc) {
         await db.post(doc);
         });
        }

        上面代碼會(huì)報(bào)錯(cuò),因?yàn)?await 用在普通函數(shù)之中了。但是,如果將 forEach 方法的參數(shù)改成 async 函數(shù),也有問(wèn)題。

        async function dbFuc(db) {
         let docs = [{}, {}, {}];
        
         // 可能得到錯(cuò)誤結(jié)果
         docs.forEach(async function (doc) {
         await db.post(doc);
         });
        }

        上面代碼可能不會(huì)正常工作,原因是這時(shí)三個(gè) db.post 操作將是并發(fā)執(zhí)行,也就是同時(shí)執(zhí)行,而不是繼發(fā)執(zhí)行。正確的寫法是采用 for 循環(huán)。

        async function dbFuc(db) {
         let docs = [{}, {}, {}];
         for (let doc of docs) {
         await db.post(doc);
         }
        }

        如果確實(shí)希望多個(gè)請(qǐng)求并發(fā)執(zhí)行,可以使用 Promise.all 方法。

        async function dbFuc(db) {
         let docs = [{}, {}, {}];
         let promises = docs.map((doc) => db.post(doc));
         let results = await Promise.all(promises);
         console.log(results);
        }
        // 或者使用下面的寫法
        async function dbFuc(db) {
         let docs = [{}, {}, {}];
         let promises = docs.map((doc) => db.post(doc));
         let results = [];
         for (let promise of promises) {
         results.push(await promise);
         }
         console.log(results);
        }

        總結(jié)

        以上所述是小編給大家介紹的js 中async 函數(shù)的含義和用法,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)歡迎給我留言,小編會(huì)及時(shí)回復(fù)大家的!

        聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        深入理解js 中async 函數(shù)的含義和用法

        深入理解js 中async 函數(shù)的含義和用法:一、終極解決 異步操作是 JavaScript 編程的麻煩事,麻煩到一直有人提出各種各樣的方案,試圖解決這個(gè)問(wèn)題。 從最早的回調(diào)函數(shù),到 Promise 對(duì)象,再到 Generator 函數(shù),每次都有所改進(jìn),但又讓人覺(jué)得不徹底。它們都有額外的復(fù)雜性,都需要理解抽象的底層運(yùn)行
        推薦度:
        標(biāo)簽: 使用 含義 js
        • 熱門焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 最近中文字幕大全免费版在线| 永久免费av无码网站yy| 一个人免费观看www视频在线| 亚洲第一区香蕉_国产a| 无码午夜成人1000部免费视频| 深夜国产福利99亚洲视频| 国产精品亚洲专区无码牛牛| 国产精品免费一级在线观看| 亚洲日韩国产一区二区三区在线 | h视频在线观看免费| 亚洲欧洲自拍拍偷精品 美利坚 | 亚洲成人一区二区| 青青免费在线视频| 亚洲爽爽一区二区三区| sss在线观看免费高清| 亚洲AV午夜福利精品一区二区| 两个人看的www视频免费完整版| 亚洲精品无码永久在线观看你懂的| 最好免费观看高清在线| 亚洲电影免费观看| 国产精品国产亚洲区艳妇糸列短篇| 日本人护士免费xxxx视频| 免费在线观看自拍性爱视频| 亚洲区不卡顿区在线观看| 国产日韩AV免费无码一区二区| 亚洲大片在线观看| 成人性生交大片免费看无遮挡| ww亚洲ww在线观看国产| 免费人成网站7777视频| 四虎国产精品免费永久在线| 亚洲AV无码国产精品麻豆天美 | 2019中文字幕在线电影免费| 一本色道久久综合亚洲精品蜜桃冫| 国产一级淫片免费播放电影| 中文字幕在线成人免费看| 亚洲人成激情在线播放| 亚洲av无码成人精品区在线播放| 国产成人AV免费观看| 亚洲三级在线观看| 美腿丝袜亚洲综合| 国产精品成人免费视频网站京东|