成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Promise 基本原理 & 異步

mtunique / 2196人閱讀

摘要:追加在本輪循環(huán)的異步任務(wù)追加在次輪循環(huán)的異步任務(wù)規(guī)定,和的回調(diào)函數(shù),追加在本輪循環(huán),即同步任務(wù)一旦執(zhí)行完成,就開始執(zhí)行它們。

author: 陳家賓
email: [email protected]
date: 2018/2/23
Promise 基本實(shí)現(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 是個(gè) 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?!!

異步任務(wù)可以分成兩種。

追加在本輪循環(huán)的異步任務(wù)

追加在次輪循環(huán)的異步任務(wù)

Node 規(guī)定,process.nextTickPromise的回調(diào)函數(shù),追加在本輪循環(huán),即同步任務(wù)一旦執(zhí)行完成,就開始執(zhí)行它們。而setTimeoutsetInterval、setImmediate的回調(diào)函數(shù),追加在次輪循環(huán)。

異步分兩種已經(jīng)讓我大開眼界,但在我的知識(shí)世界里,Promise 不是用 setTimeout 來實(shí)現(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,這里會(huì)根據(jù)不同環(huán)境來采用不同的實(shí)現(xiàn)方式,瀏覽器中主要用了 MutationObserver 和 setTimeout

我們先來看一下 MutationObserver 的兼容性(下圖參考 https://developer.mozilla.org...)

由上圖可知,使用 polyfill,從以上版本開始,Promise 是由 MutationObserver 實(shí)現(xiàn)的本輪循環(huán)的異步任務(wù),低于以上版本的,則是由 setTimeout 實(shí)現(xiàn)的次輪循環(huán)的異步任務(wù)(本輪循環(huán)在次輪循環(huán)之前執(zhí)行)。其帶來的具體差別如下:

// ie11
setTimeout(function () {console.log(1)});
Promise.resolve().then(function () {
  console.log(2);
});
// 輸出結(jié)果為 2 1

// ie10
setTimeout(function () {console.log(1)});
Promise.resolve().then(function () {
  console.log(2);
});
// 輸出結(jié)果為 1 2
其他 shim VS polyfill

shim,給瀏覽器帶來新 API 的庫,如 jQuery

polyfill 則是針對瀏覽器的一種補(bǔ)丁,一種補(bǔ)充,使其行為與其他瀏覽器保持一致,如 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 定時(shí)器詳解》,阮一峰,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...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/107583.html

相關(guān)文章

  • ES6&ES7中的異步之a(chǎn)sync函數(shù)

    摘要:更好的語義和分別表示異步和等待,比起和更容易理解。前邊聲明關(guān)鍵字,表示內(nèi)部有內(nèi)部操作,調(diào)用函數(shù)會(huì)返回一個(gè)對象。等價(jià)于其中函數(shù)就是自動(dòng)執(zhí)行器。 async函數(shù) 定義 async函數(shù)其實(shí)就是之前說過的Generator的語法糖,用于實(shí)現(xiàn)異步操作。它是ES2017的新標(biāo)準(zhǔn)。 讀取兩個(gè)文件: const fs = require(fs) const readFile = function(f...

    dongxiawu 評論0 收藏0
  • js異步從入門到放棄(實(shí)踐篇) — 常見寫法&面試題解析

    摘要:前文該系列下的前幾篇文章分別對不同的幾種異步方案原理進(jìn)行解析,本文將介紹一些實(shí)際場景和一些常見的面試題。流程調(diào)度里比較常見的一種錯(cuò)誤是看似串行的寫法,可以感受一下這個(gè)例子判斷以下幾種寫法的輸出結(jié)果辨別輸出順序這類題目一般出現(xiàn)在面試題里。 前文 該系列下的前幾篇文章分別對不同的幾種異步方案原理進(jìn)行解析,本文將介紹一些實(shí)際場景和一些常見的面試題。(積累不太夠,后面想到再補(bǔ)) 正文 流程調(diào)度...

    Awbeci 評論0 收藏0
  • Promise & Generator——幸福地用同步方法寫異步JavaScript

    摘要:在這里看尤雨溪大神的這篇小短文,非常精簡扼要地介紹了當(dāng)前常用的。根據(jù)尤雨溪大神的說法,的也只是的語法糖而已。對象有三種狀態(tài),,。對象通過和方法來規(guī)定異步結(jié)束之后的操作正確處理函數(shù)錯(cuò)誤處理函數(shù)。方便進(jìn)行后續(xù)的成功處理或者錯(cuò)誤處理。 最近在寫一個(gè)自己的網(wǎng)站的時(shí)候(可以觀摩一下~Colors),在無意識(shí)中用callback寫了一段嵌套了5重回調(diào)函數(shù)的可怕的代碼?;剡^神來的時(shí)候被自己嚇了一跳,...

    Harpsichord1207 評論0 收藏0
  • 一文搞懂Vue3中的異步組件defineAsyncComponentAPI的用法

      為了更好的提升用戶的體驗(yàn),我們要縮短加載的時(shí)間,要一些組件僅在需要的時(shí)候才加載這樣極大的節(jié)約加載時(shí)間,提升用戶訪問效果?! ‖F(xiàn)在我們可以用Vue3來作為一個(gè)實(shí)現(xiàn)方法,即defineAsyncComponent,這個(gè)方法可以傳遞兩種類型的參數(shù),分別是函數(shù)類型和對象類型,接下來我們分別學(xué)習(xí)。  傳遞工廠函數(shù)作為參數(shù)  defineAsyncComponent方法接收一個(gè)工廠函數(shù)是它的基本用法,這個(gè)...

    3403771864 評論0 收藏0
  • 解析關(guān)于JavaScript事件循環(huán)同步任務(wù)與異步任務(wù)

      學(xué)習(xí)一門知識(shí),有些內(nèi)容必須要提前明白,比如在學(xué)習(xí)js中同步異步的問題前,需要明白,js是單線程的,為什么它得是單線程的呢?現(xiàn)在先從它應(yīng)用的場景來說,就是用來讓用戶與頁面進(jìn)行交互的吧。假如有js是多線程的,那在這個(gè)線程里面,用戶點(diǎn)擊某個(gè)按鈕會(huì)增加一個(gè)DOM節(jié)點(diǎn),在另一個(gè)線程里面,用戶點(diǎn)擊這個(gè)按鈕又會(huì)刪除一個(gè)DOM節(jié)點(diǎn),那么此時(shí)js就不知道該聽誰的了。這就是為什么會(huì)出現(xiàn)同步異步。假設(shè)沒有異步,那么...

    3403771864 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<