Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 日本天堂免费,日本一道本中文字幕,国产精品亚洲综合天堂夜夜

          整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          JavaScript中的async/await

          文同步本人掘金平臺的原創(chuàng)翻譯文章:https://juejin.cn/post/6844903834456702984

          異步的JavaScript從未如何簡單!過去段時間,我們使用回調(diào)。然后,我們使用promises。現(xiàn)在,我們有了異步功能函數(shù)。

          異步函數(shù)能夠使得(我們)編寫異步JavaScript更加容易,但是,它自帶一套陷阱,對初學者很不友好。

          在這個由兩部分組成的文章中,我想分享下你需要了解的有關(guān)異步函數(shù)的內(nèi)容。【PS:另一部分暫不打算翻譯】

          異步功能

          異步功能函數(shù)包含async關(guān)鍵詞。你可以在正常的函數(shù)聲明中使用它:

          async function functionName (arguments) {
            // Do something asynchronous
          }
          復(fù)制代碼

          你也可以使用箭頭函數(shù)。

          const functionName = async (arguments) => {
            // Do something asynchronous
          }
          復(fù)制代碼

          異步函數(shù)總是返回promises

          (異步函數(shù))它不管你返回什么。其返回值都是promise。

          const getOne = async _ => { 
            return 1 
          } 
          
          const promise = getOne()
          console.log(promise) // Promise 
          復(fù)制代碼

          筆記:在接著往前讀之前,你應(yīng)該知道什么是JavaScript Promises知識點,以及如何使用它們。否則,它會開始變得混亂。這篇文章會幫助你熟悉JavaScript Promise。

          await關(guān)鍵字

          當你調(diào)用promise時,你會在then中處理下一步,如下:

          const getOne = async _ => { 
            return 1 
          } 
          
          getOne()
            .then(value => {
              console.log(value) // 1
            })
          復(fù)制代碼

          await關(guān)鍵字允許你等待promise去解析。一旦解析完promise,它就會返回參數(shù)傳遞給then調(diào)用。

          const test = async _ => {
            const one = await getOne()
            console.log(one) // 1
          }
          
          test()
          復(fù)制代碼

          返回await

          在返回承諾(promise)之前沒有必要等待(await)。你可以直接退回承諾。

          如果你return await些內(nèi)容,則你首先是解決了原先promise。然后,你從已經(jīng)解析的內(nèi)容(resolved value)創(chuàng)建新的promise。return await真的沒做什么有效的東西。無需額外的步驟。

          // Don't need to do this 
          const test = async _ => {
            return await getOne()
          }
          
          test()
            .then(value => {
              console.log(value) // 1
            })
          復(fù)制代碼
          // Do this instead
          const test = async _ => {
            return getOne()
          }
          
          test()
            .then(value => {
              console.log(value) // 1
            })
          復(fù)制代碼

          注意:如果你不需要await,則不需要使用異步功能(async function)。上面的例子可以改寫如下:

          // Do this instead
          const test = _ => {
            return getOne()
          }
          
          test()
            .then(value => {
              console.log(value) // 1
            })
          復(fù)制代碼

          處理錯誤

          如果一個promise出錯了,你可以使用catch調(diào)用來處理它,如下所示:

          const getOne = async (success = true) => { 
            if (success) return 1
            throw new Error('Failure!')
          } 
          
          getOne(false)
            .catch(error => console.log(error)) // Failure!
          復(fù)制代碼

          如果你想在一個異步函數(shù)中處理錯誤,你需要調(diào)用try/catch。

          const test = async _ => {
            try {
              const one = await getOne(false)
            } catch (error) {
              console.log(error) // Failure!
            }
          }
          
          test()
          復(fù)制代碼

          如果你有多個await關(guān)鍵字,錯誤處理可能變得很難看...

          const test = async _ => {
            try {
              const one = await getOne(false)
            } catch (error) {
              console.log(error) // Failure!
            }
          
            try {
              const two = await getTwo(false)
            } catch (error) {
              console.log(error) // Failure!
            }
          
            try {
              const three = await getThree(false)
            } catch (error) {
              console.log(error) // Failure!
            }
          }
          
          test()
          復(fù)制代碼

          還有更好的方法。

          我們知道異步函數(shù)總是返回一個promise。當我們調(diào)用promise時,我們可以在catch調(diào)用中處理錯誤。這意味著我們可以通過添加.catch來處理異步函數(shù)中的任何錯誤。

          const test = async _ => {
            const one = await getOne(false)
            const two = await getTwo(false)
            const three = await getThree(false)
          }
          
          test()
            .catch(error => console.log(error)))
          復(fù)制代碼

          注意:Promise的catch方法只允許你捕獲一個錯誤。

          多個awaits

          await阻止JavaScript執(zhí)行下一行代碼,直到promise解析為止。這可能會導致代碼執(zhí)行速度減慢的意外效果。

          為了實際演示這點,我們需要在解析promise之前創(chuàng)建一個延遲。我們可以使用sleep功能來創(chuàng)建延遲。

          const sleep = ms => {
            return new Promise(resolve => setTimeout(resolve, ms))
          }
          復(fù)制代碼

          ms是解析前等待的毫秒數(shù)。如果你傳入1000到sleep函數(shù),JavaScript將等待一秒才能解析promise。

          // Using Sleep
          console.log('Now')
          sleep(1000)
            .then(v => { 
              console.log('After one second') 
            })
          復(fù)制代碼

          假設(shè)getOne需要一秒來解析。為了創(chuàng)建這個延遲,我們將1000(一秒)傳入到sleep。一秒過后,sleeppromise解析后,我們返回值1。

          const getOne = _ => {
            return sleep(1000).then(v => 1)
          }
          復(fù)制代碼

          如果你使用await getOne(),你會發(fā)現(xiàn)在getOne解析之前需要一秒鐘。

          const test = async _ => {
            console.log('Now')
          
            const one = await getOne()
            console.log(one)
          }
          
          test()
          復(fù)制代碼

          現(xiàn)在,假設(shè)你需要處理三個promises。每個promise都有一秒鐘的延遲。

          const getOne = _ => {
            return sleep(1000).then(v => 1)
          }
          
          const getTwo = _ => {
            return sleep(1000).then(v => 2)
          }
          
          const getThree = _ => {
            return sleep(1000).then(v => 3)
          }
          復(fù)制代碼

          如果你連續(xù)await這三個promises,你將要等待三秒才能解析完所有promises。這并不好,因為我們強迫JavaScript在做我們需要做的事情之前等待了兩秒鐘。

          const test = async _ => {
            const one = await getOne()
            console.log(one)
          
            const two = await getTwo()
            console.log(two)
          
            const three = await getThree()
            console.log(three)
          
            console.log('Done')
          }
          
          test()
          復(fù)制代碼

          如果getOne,getTwo和getThree可以同時獲取,你將節(jié)省兩秒鐘。你可以使用Promise.all同時獲取這三個promises。

          有三個步驟:

          1. 創(chuàng)建三個promises
          2. 將三個promises添加到一個數(shù)組中
          3. 使用Promise.all來awaitpromises數(shù)組

          如下所示:

          const test = async _ => {
            const promises = [getOne(), getTwo(), getThree()]
            console.log('Now')
          
            const [one, two, three] = await Promise.all(promises)
            console.log(one)
            console.log(two)
            console.log(three)
          
            console.log('Done')
          }
          
          test()
          復(fù)制代碼

          這就是你需要了解的基本異步功能函數(shù)!我希望這篇文章為你掃除了些障礙。

          筆記:這篇文章是Learn JavaScript的修改摘錄。如果你發(fā)現(xiàn)本文有用,你可能需要去查看它。

          ello~各位親愛的看官老爺們大家好。估計大家都聽過,盡量將 CSS 放頭部, JS 放底部,這樣可以提高頁面的性能。然而,為什么呢?大家有考慮過么?很長一段時間,我都是知其然而不知其所以然,強行背下來應(yīng)付考核當然可以,但實際應(yīng)用中必然一塌糊涂。因此洗(wang)心(yang)革(bu)面(lao),小結(jié)一下最近玩出來的成果。

          友情提示,本文也是小白向為主,如果直接想看結(jié)論可以拉到最下面看的~

          推薦下我的前端群:524262608,不定期分享干貨,包括我自己整理的一份2017最新的前端資料和零基礎(chǔ)入門教程,歡迎初學和進階中的小伙伴。

          由于關(guān)系到文件的讀取,那是肯定需要服務(wù)器的,我會把全部的文件放在 github 上,給我點個 star 我會開心!掘金上再給我點個 贊 我就更開心了~

          node 端唯一需要解釋一下的是這個函數(shù):

          function sleep(time) { return new Promise(function(res) {
          setTimeout(() => {
          res()
          }, time);
          })
          }

          嗯!其實就延時啦。如果 CSS 或者 JS 文件名有 sleep3000 之類的前綴時,意思就是延遲3000毫秒才會返回這文件。

          下文使用的 HTML 文件是長這樣的:

          <!DOCTYPE html>
          <html lang="en">
          <head>
          <meta charset="UTF-8">
          <title>Title</title>
          <style>
           div { width: 100px; height: 100px; background: lightgreen;
           } </style>
          </head>
          <body>
          <div></div>
          </body>
          </html>

          我會在其中插入不同的 JS 和 CSS 。

          而使用的 common.css ,不論有沒有前綴,內(nèi)容都是這樣的:

          div { background: red;
          }

          好了,話不多數(shù),開始正文!

          關(guān)于 CSS ,大家肯定都知道的是 <link> 標簽放在頭部性能會高一點,少一點人知道如果 <script> 與 <link> 同時在頭部的話, <script> 在上可能會更好。這是為什么呢?下面我們一起來看一下 CSS 對 DOM 的影響是什么。

          CSS 不會阻塞 DOM 的解析

          注意哦!這里說的是 DOM 解析,證明的例子如下,首先在頭部插入 <script defer src="/js/logDiv.js"></script> , JS 文件的內(nèi)容是:

          const div = document.querySelecot('div');
          console.log(div);

          defer 屬性相信大家也很熟悉了,MDN對此的描述是用來通知瀏覽器該腳本將在文檔完成解析后,觸發(fā) DOMContentLoaded 事件前執(zhí)行。設(shè)置這個屬性,能保證 DOM 解析后馬上打印出 div 。

          之后將 <link rel="stylesheet" href="/css/sleep3000-common.css"> 插入 HTML 文件的任一位置,打開瀏覽器,可以看到是首先打印出 div 這個 DOM 節(jié)點,過3s左右之后才渲染出一個淺藍色的 div 。這就證明了 CSS 是不會阻塞 DOM 的解析的,盡管 CSS 下載需要3s,但這個過程中,瀏覽器不會傻等著 CSS 下載完,而是會解析 DOM 的。

          這里簡單說一下,瀏覽器是解析 DOM 生成 DOM Tree ,結(jié)合 CSS 生成的 CSS Tree ,最終組成 render tree ,再渲染頁面。由此可見,在此過程中 CSS 完全無法影響 DOM Tree ,因而無需阻塞 DOM 解析。然而, DOM Tree 和 CSS Tree 會組合成 render tree ,那 CSS 會不會頁面阻塞渲染呢?

          CSS 阻塞頁面渲染

          其實這一點,剛才的例子已經(jīng)說明了,如果 CSS 不會阻塞頁面阻塞渲染,那么 CSS 文件下載之前,瀏覽器就會渲染出一個淺綠色的 div ,之后再變成淺藍色。瀏覽器的這個策略其實很明智的,想象一下,如果沒有這個策略,頁面首先會呈現(xiàn)出一個原始的模樣,待 CSS 下載完之后又突然變了一個模樣。用戶體驗可謂極差,而且渲染是有成本的。

          因此,基于性能與用戶體驗的考慮,瀏覽器會盡量減少渲染的次數(shù), CSS 順理成章地阻塞頁面渲染。

          然而,事情總有奇怪的,請看這例子, HTML 頭部結(jié)構(gòu)如下:

          <header>
          <link rel="stylesheet" href="/css/sleep3000-common.css">
          <script src="/js/logDiv.js"></script></header>

          但思考一下這會產(chǎn)生什么結(jié)果呢?

          答案是瀏覽器會轉(zhuǎn)圈圈三秒,但此過程中不會打印任何東西,之后呈現(xiàn)出一個淺藍色的 div ,再打印出 null 。結(jié)果好像是 CSS 不單阻塞了頁面渲染,還阻塞了 DOM 的解析啊!稍等,在你打算掀桌子瘋狂吐槽我之前,請先思考一下是什么阻塞了 DOM 的解析,剛才已經(jīng)證明了 CSS 是不會阻塞的,那么阻塞了頁面解析其實是 JS !但明明 JS 的代碼如此簡單,肯定不會阻塞這么久,那就是 JS 在等待 CSS 的下載,這是為什么呢?

          仔細思考一下,其實這樣做是有道理的,如果腳本的內(nèi)容是獲取元素的樣式,寬高等 CSS 控制的屬性,瀏覽器是需要計算的,也就是依賴于 CSS 。瀏覽器也無法感知腳本內(nèi)容到底是什么,為避免樣式獲取,因而只好等前面所有的樣式下載完后,再執(zhí)行 JS 。因而造成了之前例子的情況。

          所以,看官大人明白為何 <script> 與 <link> 同時在頭部的話, <script> 在上可能會更好了么?之所以是可能,是因為如果 <link> 的內(nèi)容下載更快的話,是沒影響的,但反過來的話, JS 就要等待了,然而這些等待的時間是完全不必要的。

          JS

          JS ,也就是 <script> 標簽,估計大家都很熟悉了,不就是阻塞 DOM 解析和渲染么。然而,其中其實還是有一點細節(jié)可以考究一下的,我們一起來好好看看。

          JS 阻塞 DOM 解析

          首先我們需要一個新的 JS 文件名為 blok.js ,內(nèi)容如下:

          <body>
          <div></div>
          <script src="/js/sleep3000-logDiv.js"></script>
          <style>
           div { background: lightgrey;
           } </style>
          <script src="/js/sleep5000-logDiv.js"></script>
          <link rel="stylesheet" href="/css/common.css"></body>

          這個例子也是很極端的例子,但不妨礙它透露給我們很多重要的信息。想象一下,頁面會怎樣呢?

          答案是先淺綠色,再淺灰色,最后淺藍色。由此可見,每次碰到 <script> 標簽時,瀏覽器都會渲染一次頁面。這是基于同樣的理由,瀏覽器不知道腳本的內(nèi)容,因而碰到腳本時,只好先渲染頁面,確保腳本能獲取到最新的 DOM 元素信息,盡管腳本可能不需要這些信息。

          小結(jié)

          綜上所述,我們得出這樣的結(jié)論:

          CSS 不會阻塞 DOM 的解析,但會阻塞 DOM 渲染。

          JS 阻塞 DOM 解析,但瀏覽器會"偷看" DOM ,預(yù)先下載相關(guān)資源。

          最后還是要推薦下我的前端群:524262608,不定期分享干貨,包括我自己整理的一份2017最新的前端資料和零基礎(chǔ)入門教程,歡迎初學和進階中的小伙伴。

          瀏覽器遇到 <script> 且沒有 defer 或 async 屬性的 標簽時,會觸發(fā)頁面渲染,因而如果前面 CSS 資源尚未加載完畢時,瀏覽器會等待它加載完畢在執(zhí)行腳本。

          所以,你現(xiàn)在明白為何 <script> 最好放底部, <link> 最好放頭部,如果頭部同時有 <script> 與 <link> 的情況下,最好將 <script> 放在 <link> 上面了嗎?

          web前端學習方法經(jīng)驗可以關(guān)注我的微信公眾號:‘學習web前端’,每天更新案例源碼或經(jīng)驗分享,關(guān)注后回復(fù)‘給我資料’可以領(lǐng)取一套完整的學習視頻


          主站蜘蛛池模板: 亚洲AV噜噜一区二区三区| 国产伦精品一区二区三区无广告| 99精品国产一区二区三区不卡| 在线|一区二区三区| 亚洲色偷偷偷网站色偷一区| 国产SUV精品一区二区88L| 在线精品一区二区三区电影| 无码欧精品亚洲日韩一区夜夜嗨| 国产精品盗摄一区二区在线| 国产乱码精品一区二区三区四川| 国产成人无码精品一区在线观看| 国产一区二区在线看| 国模无码一区二区三区| 亚洲一区二区三区AV无码| 国产成人精品一区二三区| 亚洲国产精品第一区二区三区| 清纯唯美经典一区二区| 国内精品无码一区二区三区| 91精品一区二区三区在线观看| 亚洲av无一区二区三区| 亚洲日本中文字幕一区二区三区| 国产在线无码一区二区三区视频 | 亚洲码欧美码一区二区三区| 亚洲精品精华液一区二区 | 国产精品第一区第27页| 国产午夜福利精品一区二区三区 | 人成精品视频三区二区一区| 日本不卡一区二区三区| 日韩一区二区在线免费观看| 丝袜无码一区二区三区| 精品一区二区三区在线视频观看| 国产免费一区二区三区免费视频| 欧美日韩一区二区成人午夜电影| 国产在线一区二区三区av| 亚洲丶国产丶欧美一区二区三区| 奇米精品视频一区二区三区| 日本一区二区不卡视频| 日韩精品无码一区二区视频| 一区二区三区视频免费观看| 亚洲一区二区三区丝袜| 中文字幕人妻第一区|