<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之旅 廣告
                在使用[`Promise.resolve(value)`](http://liubin.github.io/promises-book/#Promise.resolve)?等方法的時候,如果promise對象立刻就能進入resolve狀態的話,那么你是不是覺得?`.then`?里面指定的方法就是同步調用的呢? 實際上,?`.then`?中指定的方法調用是異步進行的。 ~~~ var promise = new Promise(function (resolve){ console.log("inner promise"); // 1 resolve(42); }); promise.then(function(value){ console.log(value); // 3 }); console.log("outer promise"); // 2 ~~~ 執行上面的代碼會輸出下面的log,從這些log我們清楚地知道了上面代碼的執行順序。 ~~~ inner promise // 1 outer promise // 2 42 // 3 ~~~ 由于JavaScript代碼會按照文件的從上到下的順序執行,所以最開始?`<1>`?會執行,然后是?`resolve(42);`?被執行。這時候?`promise`?對象的已經變為確定狀態,FulFilled被設置為了?`42`?。 下面的代碼?`promise.then`?注冊了?`<3>`?這個回調函數,這是本專欄的焦點問題。 由于?`promise.then`?執行的時候promise對象已經是確定狀態,從程序上說對回調函數進行同步調用也是行得通的。 但是即使在調用?`promise.then`?注冊回調函數的時候promise對象已經是確定的狀態,Promise也會以異步的方式調用該回調函數,這是在Promise設計上的規定方針。 因此?`<2>`?會最先被調用,最后才會調用回調函數?`<3>`?。 為什么要對明明可以以同步方式進行調用的函數,非要使用異步的調用方式呢? ## 2.3.1\. 同步調用和異步調用同時存在導致的混亂 其實在Promise之外也存在這個問題,這里我們以一般的使用情況來考慮此問題。 這個問題的本質是接收回調函數的函數,會根據具體的執行情況,可以選擇是以同步還是異步的方式對回調函數進行調用。 下面我們以?`onReady(fn)`?為例進行說明,這個函數會接收一個回調函數進行處理。 mixed-onready.js ~~~ function onReady(fn) { var readyState = document.readyState; if (readyState === 'interactive' || readyState === 'complete') { fn(); } else { window.addEventListener('DOMContentLoaded', fn); } } onReady(function () { console.log('DOM fully loaded and parsed'); }); console.log('==Starting=='); ~~~ [mixed-onready.js](http://liubin.github.io/promises-book/#mixed-onready.js)會根據執行時DOM是否已經裝載完畢來決定是對回調函數進行同步調用還是異步調用。 如果在調用onReady之前DOM已經載入的話 對回調函數進行同步調用 如果在調用onReady之前DOM還沒有載入的話 通過注冊?`DOMContentLoaded`?事件監聽器來對回調函數進行異步調用 因此,如果這段代碼在源文件中出現的位置不同,在控制臺上打印的log消息順序也會不同。 為了解決這個問題,我們可以選擇統一使用異步調用的方式。 async-onready.js ~~~ function onReady(fn) { var readyState = document.readyState; if (readyState === 'interactive' || readyState === 'complete') { setTimeout(fn, 0); } else { window.addEventListener('DOMContentLoaded', fn); } } onReady(function () { console.log('DOM fully loaded and parsed'); }); console.log('==Starting=='); ~~~ 關于這個問題,在?[Effective JavaScript](http://effectivejs.com/)?的?**第67項 不要對異步回調函數進行同步調用**?中也有詳細介紹。 > * 絕對不能對異步回調函數(即使在數據已經就緒)進行同步調用。 > * 如果對異步回調函數進行同步調用的話,處理順序可能會與預期不符,可能帶來意料之外的后果。 > * 對異步回調函數進行同步調用,還可能導致棧溢出或異常處理錯亂等問題。 > * 如果想在將來某時刻調用異步回調函數的話,可以使用?`setTimeout`?等異步API。 > > > Effective JavaScript > — David Herman 前面我們看到的?`promise.then`?也屬于此類,為了避免上述中同時使用同步、異步調用可能引起的混亂問題,Promise在規范上規定**Promise只能使用異步調用方式**?。 最后,如果將上面的?`onReady`?函數用Promise重寫的話,代碼如下面所示。 onready-as-promise.js ~~~ function onReadyPromise() { return new Promise(function (resolve, reject) { var readyState = document.readyState; if (readyState === 'interactive' || readyState === 'complete') { resolve(); } else { window.addEventListener('DOMContentLoaded', resolve); } }); } onReadyPromise().then(function () { console.log('DOM fully loaded and parsed'); }); console.log('==Starting=='); ~~~ 由于Promise保證了每次調用都是以異步方式進行的,所以我們在實際編碼中不需要調用?`setTimeout`?來自己實現異步調用。
                  <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>

                              哎呀哎呀视频在线观看