<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 一、概述 JavaScript是單線程模型,同時只能執行一個任務,其他任務都必須在后面排隊等待; 好處:簡單; 壞處:只要有一個任務耗時很長,后面的任務都必須排隊等著,會拖延整個程序的執行;常見的瀏覽器無響應(假死),往往就是因為某一段 JavaScript 代碼長時間運行(比如死循環),導致整個頁面卡在這個地方,其他任務無法執行; ## 二、同步任務和異步任務 同步任務:那些沒有被引擎掛起、在主線程上排隊執行的任務。只有前一個任務執行完畢,才能執行后一個任務; 異步任務:那些被引擎放在一邊,不進入主線程、而進入任務隊列的任務;只有引擎認為某個異步任務可以執行了(比如 Ajax 操作從服務器得到了結果),該任務(采用回調函數的形式)才會進入主線程執行。排在異步任務后面的代碼,不用等待異步任務結束會馬上運行,也就是說,異步任務不具有“堵塞”效應; 舉例: Ajax 操作可以當作同步任務處理,也可以當作異步任務處理,由開發者決定。如果是同步任務,主線程就等著 Ajax 操作返回結果,再往下執行;如果是異步任務,主線程在發出 Ajax 請求以后,就直接往下執行,等到 Ajax 操作有了結果,主線程再執行對應的回調函數; ## 三、異步模式 ### 回調函數 回調函數:把一個函數A當做實參專遞給另外一個函數B,在B方法執行的時候,把A執行了,我們把這種機制叫做 “回調函數機制”; 回調函數是異步操作最基本的方法; 回調函數的優點是簡單、容易理解和實現,缺點是不利于代碼的閱讀和維護,各個部分之間高度耦合,使得程序結構混亂、流程難以追蹤(尤其是多個回調函數嵌套的情況),而且每個任務只能指定一個回調函數; ~~~ function f1() { // ... } function f2() { // ... } f1(); f2(); ~~~ 上面代碼的問題在于,如果`f1`是異步操作,`f2`會立即執行,不會等到`f1`結束再執行; 可以考慮改寫`f1`,把`f2`寫成`f1`的回調函數: ~~~ function f1(callback) { // ... callback(); } function f2() { // ... } f1(f2); ~~~ ### 事件監聽 采用事件驅動模式。異步任務的執行不取決于代碼的順序,而取決于某個事件是否發生; 首先,為`f1`綁定一個事件: ~~~ f1.on('done', f2); ~~~ 當`f1`發生`done`事件,就執行`f2`; ~~~ function f1() { setTimeout(function () { // ... f1.trigger('done'); }, 1000); } ~~~ 上面代碼中,`f1.trigger('done')`表示,執行完成后,立即觸發`done`事件,從而開始執行`f2`; 這種方法的優點是比較容易理解,可以綁定多個事件,每個事件可以指定多個回調函數,而且可以去耦合,有利于實現模塊化。缺點是整個程序都要變成事件驅動型,運行流程會變得很不清晰。閱讀代碼的時候,很難看出主流程; ### 發布/訂閱 事件完全可以理解成“信號”,如果存在一個“信號中心”,某個任務執行完成,就向信號中心“發布”(publish)一個信號,其他任務可以向信號中心“訂閱”(subscribe)這個信號,從而知道什么時候自己可以開始執行。這就叫做”[發布/訂閱模式],又稱“[觀察者模式](observer pattern); ## 四、定時器 JavaScript 提供定時執行代碼的功能,叫做定時器(timer),主要由`setTimeout()`和`setInterval()`這兩個函數來完成。它們向任務隊列添加定時任務; ## 五、Promise Promise 對象是 JavaScript 的異步操作解決方案,為異步操作提供統一接口; Promise 可以讓異步操作寫起來,就像在寫同步操作的流程,而不必一層層地嵌套回調函數; Promise 的設計思想是,所有異步任務都返回一個 Promise 實例。Promise 實例有一個`then`方法,用來指定下一步的回調函數; ~~~ var p1 = new Promise(f1); p1.then(f2); ~~~ 上面代碼中,`f1`的異步操作執行完成,就會執行`f2`; Promise 的優點在于,讓回調函數變成了規范的鏈式寫法,程序流程可以看得很清楚。它有一整套接口,可以實現許多強大的功能,比如同時執行多個異步操作,等到它們的狀態都改變以后,再執行一個回調函數;再比如,為多個回調函數中拋出的錯誤,統一指定處理方法等等; 而且,Promise 還有一個傳統寫法沒有的好處:它的狀態一旦改變,無論何時查詢,都能得到這個狀態。這意味著,無論何時為 Promise 實例添加回調函數,該函數都能正確執行。所以,你不用擔心是否錯過了某個事件或信號。如果是傳統寫法,通過監聽事件來執行回調函數,一旦錯過了事件,再添加回調函數是不會執行的; Promise 的缺點是,編寫的難度比傳統寫法高,而且閱讀代碼也不是一眼可以看懂。你只會看到一堆`then`,必須自己在`then`的回調函數里面理清邏輯; >[danger] > Promise 的回調函數屬于異步任務,會在同步任務之后執行; > Promise 的回調函數不是正常的異步任務,而是微任務(microtask)。它們的區別在于,正常任務追加到下一輪事件循環,微任務追加到本輪事件循環。這意味著,微任務的執行時間一定早于正常任務;
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看