<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          V8 9.1 正式支持頂層 await !

          共 4772字,需瀏覽 10分鐘

           ·

          2021-06-03 15:56

          作者:ConardLi

          v9.1 開(kāi)始,在 V8 中默認(rèn)啟用頂級(jí) await,并且在沒(méi)有 --harmony-top-level-await 配置的情況下也是可以用的。

          Blink 渲染引擎中,v89 版本默認(rèn)情況下已經(jīng)啟用了頂層 await

          什么是頂層 await

          在以前,我們必須在一個(gè) async 函數(shù)中才能使用 await,如果直接在一個(gè)模塊最外層使用 await 會(huì)拋出 SyntaxError 異常,為此我們通常會(huì)在外面包裹一個(gè)立即執(zhí)行函數(shù):

          await Promise.resolve(console.log('??'));
          // → SyntaxError: await is only valid in async function

          (async function({
            await Promise.resolve(console.log('??'));
            // → ??
          }());

          現(xiàn)在我們可以在整個(gè)模塊的最外層直接使用 await,這讓我們的整個(gè)模塊看一來(lái)就像一個(gè)巨大的 async 函數(shù)。

          await Promise.resolve(console.log('??'));
          // → ??

          注意,頂層 await 僅僅是允許我們?cè)谀K的最外層允許使用 await,傳統(tǒng)的 script 標(biāo)簽或非 async 函數(shù)均不能直接使用。

          為什么要引入頂層 await

          下面舉一個(gè)我們實(shí)際開(kāi)發(fā)中可能會(huì)遇到的一個(gè)問(wèn)題:

          工具庫(kù)模塊

          在一個(gè)工具庫(kù)模塊中,我們導(dǎo)出了兩個(gè)函數(shù):

          //------ library.js ------
          export const sqrt = Math.sqrt;
          export function square(x{
              return x * x;
          }
          export function diagonal(x, y{
              return sqrt(square(x) + square(y));
          }

          中間件

          在一個(gè)中間件中,我們每次需要等待一些事情執(zhí)行完,再執(zhí)行工具庫(kù)導(dǎo)出的兩個(gè)函數(shù):

          //------ middleware.js ------
          import { square, diagonal } from './library.js';

          console.log('From Middleware');

          let squareOutput;
          let diagonalOutput;

          // IIFE
           (async () => {
               await delay(1000);
               squareOutput = square(13);
               diagonalOutput = diagonal(125);
           })();

          function delay(delayInms{
            return new Promise(resolve => {
              setTimeout(() => {
                resolve(console.log('??'));
              }, delayInms);
            });
          }

          export {squareOutput,diagonalOutput};

          主程序

          在主程序中,我們要調(diào)用中間件導(dǎo)出的兩個(gè)值,但是我們并不能直接立刻拿到結(jié)果,而是必須自己寫(xiě)一個(gè)異步等待的代碼才能拿到:

          //------ main.js ------
          import { squareOutput, diagonalOutput } from './middleware.js';

          console.log(squareOutput); // undefined
          console.log(diagonalOutput); // undefined
          console.log('From Main');

          setTimeout(() => console.log(squareOutput), 2000);
          //169

          setTimeout(() => console.log(diagonalOutput), 2000);
          //13

          解決方案

          這時(shí),我們可能就會(huì)用到我們的主角,頂層 await:


          //------ middleware.js ------
          import { square, diagonal } from './library.js';

          console.log('From Middleware');

          let squareOutput;
          let diagonalOutput;

          //使用頂層 await 
          await delay(1000);
          squareOutput = square(13);
          diagonalOutput = diagonal(125);

          function delay(delayInms{
            return new Promise(resolve => {
              setTimeout(() => {
                resolve(console.log('??'));
              }, delayInms);
            });
          }

          export {squareOutput,diagonalOutput};

          //------ main.js ------
          import { squareOutput, diagonalOutput } from './middleware.js';

          console.log(squareOutput); // 169
          console.log(diagonalOutput); // 13
          console.log('From Main');

          setTimeout(() => console.log(squareOutput), 2000);// 169

          setTimeout(() => console.log(diagonalOutput), 2000); // 13

          在以上的代碼中, main.js 會(huì)等待 middleware.js 中的 await promiseresolve 后,才會(huì)執(zhí)行它的代碼,是不是非常方便!

          其他應(yīng)用場(chǎng)景

          動(dòng)態(tài)依賴導(dǎo)入

          這允許在模塊的運(yùn)行時(shí)環(huán)境中確認(rèn)依賴項(xiàng),在開(kāi)發(fā)/生產(chǎn)環(huán)境切換、國(guó)際化等場(chǎng)景中非常有用。

          const strings = await import(`/i18n/${navigator.language}`);

          資源初始化

          const connection = await dbConnector();

          這允許模塊申請(qǐng)資源,同時(shí)也可以在模塊不能使用時(shí)拋出錯(cuò)誤。

          依賴回退

          下面的例子首先會(huì)從 CDN A 加載 JavaScript 庫(kù),如果它加載失敗會(huì)將 CDN B 作為備份加載。

          let jQuery;
          try {
            jQuery = await import('https://cdn-a.example.com/jQuery');
          catch {
            jQuery = await import('https://cdn-b.example.com/jQuery');
          }

          模塊的執(zhí)行順序

          JavaScript 中一個(gè)使用 await 的巨大改變是模塊樹(shù)執(zhí)行順序的變化。JavaScript 引擎在 post-order traversal(后順序遍歷) (opens new window)中執(zhí)行模塊:先從模塊樹(shù)左側(cè)子樹(shù)開(kāi)始,模塊被執(zhí)行,導(dǎo)出它們的綁定,然后同級(jí)也被執(zhí)行,接著執(zhí)行父級(jí)。算法會(huì)遞歸運(yùn)行,直到執(zhí)行模塊樹(shù)的根節(jié)點(diǎn)。

          在頂層 await 之前,此順序始終是同步的和確定性的:在代碼的多次運(yùn)行之間,可以保證代碼樹(shù)以相同的順序執(zhí)行。有了頂層 await 后,就存在相同的保證,除非你不使用頂層 await

          在模塊中使用頂層 await 時(shí):

          • 等待 await 執(zhí)行完成后才會(huì)執(zhí)行當(dāng)前模塊。
          • 子模塊執(zhí)行完 await,并且包括所有的同級(jí)模塊執(zhí)行完,并導(dǎo)出綁定,才會(huì)執(zhí)行父模塊。
          • 假設(shè)代碼樹(shù)中沒(méi)循環(huán)或者其它 await ,同級(jí)模塊和父模塊,會(huì)以相同的同步順序繼續(xù)執(zhí)行。
          • 在 await 完成后,被調(diào)用的模塊將繼續(xù)執(zhí)行 await。
          • 只要沒(méi)有其他 await ,父模塊和子樹(shù)將繼續(xù)以同步順序執(zhí)行。

          你可能會(huì)考慮的一些問(wèn)題

          • 頂層 await 會(huì)阻斷執(zhí)行?
            • 同級(jí)之間可以執(zhí)行,最終不會(huì)阻斷。
          • 頂層 await 會(huì)阻斷資源請(qǐng)求。
            • 頂層 await 發(fā)生在模塊圖的執(zhí)行階段,此時(shí)所有資源均開(kāi)始鏈接,沒(méi)有阻塞獲取資源的風(fēng)險(xiǎn)。
          • CommonJS 模塊沒(méi)有確定如何實(shí)現(xiàn)。
            • 頂層 await 僅限于 ES 模塊,明確不支持 script 或 CommonJS 模塊。




          點(diǎn)贊在看 無(wú) bug ??

          瀏覽 55
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费男女激情内射视频网站大全 | 亚洲视频免费在线播放 | 89bbbb在线播放 | 天天综合天天做天天综合 | 波多野吉衣av |