摘要:追加在本輪循環(huán)的異步任務追加在次輪循環(huán)的異步任務規(guī)定,和的回調(diào)函數(shù),追加在本輪循環(huán),即同步任務一旦執(zhí)行完成,就開始執(zhí)行它們。
author: 陳家賓 email: 617822642@qq.com date: 2018/2/23Promise 基本實現(xiàn)
var PENDING = 0; var FULFILLED = 1; var REJECTED = 2; function Promise(fn) { var state = PENDING; var value = null; var handlers = []; doResolve(fn, resolve, reject) function fulfill(result) {} // state=fulfilled, value=result function reject(error) {} // state=rejected, value=error function resolve(result) {} // if then in result(result 是個 promise), 執(zhí)行 doResolve // else 執(zhí)行 fulfill function doResolve(fn, onFulfilled, onRejected) {} // 給 fn 傳入 resolve 和 reject 函數(shù) // resolve 函數(shù),執(zhí)行 onFulfilled // reject 函數(shù),執(zhí)行 onRejected function handle(handler) {} // if PENDING, push handler // if FULFILLED, 執(zhí)行 handler 中的 onFulfilled 函數(shù) // if REJECTED, 執(zhí)行 handler 中的 onRejected 函數(shù) this.done = function (onFulfilled, onRejected) {} // 異步(setTimeout 0)執(zhí)行 handler({onFulfilled, onRejected}) this.then = function (onFulfilled, onRejected) { var self = this return new Promise((resolve,reject)=>{ return self.done(result=>{ if onFulfilled return resolve(onFulfilled(result)) else return resolve(result) }, err=>{ if onRejected return resolve(onRejected(err)) else return reject(err) }) }) } }
基本語法
new Promsie((resolve, reject) => { // function1() resolve() }).then(() => { // function2() })
這里 function1 同步執(zhí)行,function2 異步執(zhí)行
Promise 本輪循環(huán) & 次輪循環(huán)本來以為 Promise 的內(nèi)容就到此為止了,后來看到了阮老師的一篇博客,里面說異步分兩種,what?!!
異步任務可以分成兩種。
追加在本輪循環(huán)的異步任務
追加在次輪循環(huán)的異步任務
Node 規(guī)定,process.nextTick和Promise的回調(diào)函數(shù),追加在本輪循環(huán),即同步任務一旦執(zhí)行完成,就開始執(zhí)行它們。而setTimeout、setInterval、setImmediate的回調(diào)函數(shù),追加在次輪循環(huán)。
異步分兩種已經(jīng)讓我大開眼界,但在我的知識世界里,Promise 不是用 setTimeout 來實現(xiàn)異步的嗎,為什么 Promise 和 setTimeout 還分屬于不同的異步類型里呢?
OK,馬上找一下 Promise 的 polyfill 原碼
if (isNode) { scheduleFlush = useNextTick(); } else if (BrowserMutationObserver) { // BrowserMutationObserver = window.MutationObserver scheduleFlush = useMutationObserver(); } else if (isWorker) { // typeof Uint8ClampedArray !== "undefined" && typeof importScripts !== "undefined" && typeof MessageChannel !== "undefined" scheduleFlush = useMessageChannel(); } else if (browserWindow === undefined && typeof require === "function") { // browserWindow = typeof window !== "undefined" ? window : undefined scheduleFlush = attemptVertx(); } else { scheduleFlush = useSetTimeout(); }
原來 Promise 的異步不僅僅只是 setTimeout,這里會根據(jù)不同環(huán)境來采用不同的實現(xiàn)方式,瀏覽器中主要用了 MutationObserver 和 setTimeout
我們先來看一下 MutationObserver 的兼容性(下圖參考 https://developer.mozilla.org...)
由上圖可知,使用 polyfill,從以上版本開始,Promise 是由 MutationObserver 實現(xiàn)的本輪循環(huán)的異步任務,低于以上版本的,則是由 setTimeout 實現(xiàn)的次輪循環(huán)的異步任務(本輪循環(huán)在次輪循環(huán)之前執(zhí)行)。其帶來的具體差別如下:
// ie11 setTimeout(function () {console.log(1)}); Promise.resolve().then(function () { console.log(2); }); // 輸出結果為 2 1 // ie10 setTimeout(function () {console.log(1)}); Promise.resolve().then(function () { console.log(2); }); // 輸出結果為 1 2其他 shim VS polyfill
shim,給瀏覽器帶來新 API 的庫,如 jQuery
polyfill 則是針對瀏覽器的一種補丁,一種補充,使其行為與其他瀏覽器保持一致,如 promise-polyfill
單詞 polyfill 的由來:
Polyfilla is a UK product known as Spackling Paste in the US. With that in mind: think of the browsers as a wall with cracks in it. These [polyfills] help smooth out the cracks and give us a nice smooth wall of browsers to work with.——Remy Sharp參考資料
《Node 定時器詳解》,阮一峰,2018年2月23日,http://www.ruanyifeng.com/blo...
What is the difference between a shim and a polyfill? ,stack overflow,closed at Jul 30 "15,https://stackoverflow.com/que...
《Speaking JavaScript》,Axel Rauschmayer,March 2014,http://speakingjs.com/es5/ch3...
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/107583.html
摘要:更好的語義和分別表示異步和等待,比起和更容易理解。前邊聲明關鍵字,表示內(nèi)部有內(nèi)部操作,調(diào)用函數(shù)會返回一個對象。等價于其中函數(shù)就是自動執(zhí)行器。 async函數(shù) 定義 async函數(shù)其實就是之前說過的Generator的語法糖,用于實現(xiàn)異步操作。它是ES2017的新標準。 讀取兩個文件: const fs = require(fs) const readFile = function(f...
摘要:前文該系列下的前幾篇文章分別對不同的幾種異步方案原理進行解析,本文將介紹一些實際場景和一些常見的面試題。流程調(diào)度里比較常見的一種錯誤是看似串行的寫法,可以感受一下這個例子判斷以下幾種寫法的輸出結果辨別輸出順序這類題目一般出現(xiàn)在面試題里。 前文 該系列下的前幾篇文章分別對不同的幾種異步方案原理進行解析,本文將介紹一些實際場景和一些常見的面試題。(積累不太夠,后面想到再補) 正文 流程調(diào)度...
摘要:在這里看尤雨溪大神的這篇小短文,非常精簡扼要地介紹了當前常用的。根據(jù)尤雨溪大神的說法,的也只是的語法糖而已。對象有三種狀態(tài),,。對象通過和方法來規(guī)定異步結束之后的操作正確處理函數(shù)錯誤處理函數(shù)。方便進行后續(xù)的成功處理或者錯誤處理。 最近在寫一個自己的網(wǎng)站的時候(可以觀摩一下~Colors),在無意識中用callback寫了一段嵌套了5重回調(diào)函數(shù)的可怕的代碼。回過神來的時候被自己嚇了一跳,...
為了更好的提升用戶的體驗,我們要縮短加載的時間,要一些組件僅在需要的時候才加載這樣極大的節(jié)約加載時間,提升用戶訪問效果。 現(xiàn)在我們可以用Vue3來作為一個實現(xiàn)方法,即defineAsyncComponent,這個方法可以傳遞兩種類型的參數(shù),分別是函數(shù)類型和對象類型,接下來我們分別學習。 傳遞工廠函數(shù)作為參數(shù) defineAsyncComponent方法接收一個工廠函數(shù)是它的基本用法,這個...
學習一門知識,有些內(nèi)容必須要提前明白,比如在學習js中同步異步的問題前,需要明白,js是單線程的,為什么它得是單線程的呢?現(xiàn)在先從它應用的場景來說,就是用來讓用戶與頁面進行交互的吧。假如有js是多線程的,那在這個線程里面,用戶點擊某個按鈕會增加一個DOM節(jié)點,在另一個線程里面,用戶點擊這個按鈕又會刪除一個DOM節(jié)點,那么此時js就不知道該聽誰的了。這就是為什么會出現(xiàn)同步異步。假設沒有異步,那么...
閱讀 604·2021-11-18 13:12
閱讀 1321·2021-11-15 11:39
閱讀 2480·2021-09-23 11:22
閱讀 6212·2021-09-22 15:15
閱讀 3665·2021-09-02 09:54
閱讀 2318·2019-08-30 11:10
閱讀 3250·2019-08-29 14:13
閱讀 2918·2019-08-29 12:49