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

資訊專(zhuān)欄INFORMATION COLUMN

手寫(xiě)一款符合Promise/A+規(guī)范的Promise

rubyshen / 591人閱讀

摘要:手寫(xiě)一款符合規(guī)范的長(zhǎng)篇預(yù)警有點(diǎn)長(zhǎng),可以選擇性觀看。初始狀態(tài)是,狀態(tài)可以有或者不能從轉(zhuǎn)換為或者從轉(zhuǎn)換成即只要由狀態(tài)轉(zhuǎn)換為其他狀態(tài)后,狀態(tài)就不可變更。

手寫(xiě)一款符合Promise/A+規(guī)范的Promise

長(zhǎng)篇預(yù)警!有點(diǎn)長(zhǎng),可以選擇性觀看。如果對(duì)Promise源碼不是很清楚,還是推薦從頭看,相信你認(rèn)真從頭看到尾,并且去實(shí)際操作了,肯定會(huì)有收獲的。主要是代碼部分有點(diǎn)多,不過(guò)好多都是重復(fù)的,不必?fù)?dān)心

Promise的一些用法在此不多贅述,本篇主要帶領(lǐng)你手寫(xiě)一個(gè)Promise源碼,學(xué)完你就會(huì)發(fā)現(xiàn):Promise沒(méi)有你想象中的那么難

本篇大概分為以下步驟

實(shí)現(xiàn)簡(jiǎn)單的同步Promise

增加異步功能

增加鏈?zhǔn)秸{(diào)用then

增加catch finally方法

增加all race 等方法

實(shí)現(xiàn)一個(gè)promise的延遲對(duì)象defer

最終測(cè)試

實(shí)現(xiàn)簡(jiǎn)單的同步Promise

先大概說(shuō)一下基本概念:
Promise內(nèi)部維護(hù)著三種狀態(tài),即pending,resolved和rejected。初始狀態(tài)是pending,狀態(tài)可以有pending--->relolved,或者pending--->rejected.不能從resolve轉(zhuǎn)換為rejected 或者從rejected轉(zhuǎn)換成resolved.
即 只要Promise由pending狀態(tài)轉(zhuǎn)換為其他狀態(tài)后,狀態(tài)就不可變更。
ok.知道了這些后,我們開(kāi)始手?jǐn)]代碼:

注意觀看序號(hào) 1 2 3 4 5 ...


function Promise(executor){
    let that = this;
    /** 2 定義初始的一些變量 */
    that.status = "pending";
    that.value = null;
    that.reason = null;
    
    /** 3 定義初始的成功和失敗函數(shù) */
    function resolve(value){
        /** 4 判斷狀態(tài)是不是初始狀態(tài)pending 
         *    是就轉(zhuǎn)換狀態(tài) 否則不轉(zhuǎn)換 
         *    確保狀態(tài)的變化后的不可變性 */
        if(that.status === "pending"){
            that.status = "resolved";
            that.value = value;
        }
    }
    function reject(reason){
        /** 5 同上 */
        if(that.status === "pending"){
            that.status = "rejected";
            that.reason = reason;
        }
    }
    /**
     * 1 Promise中首先傳了一個(gè)executor,它是一個(gè)函數(shù)
     *   executor函數(shù)中又傳了兩個(gè)函數(shù),分別是resolve和reject
     *   很顯然 resolve是成功回調(diào),reject是失敗的回調(diào)
     */
    executor(resolve,reject);
}

/** 6 在Promise原型上面定義then方法
 *    then方法上面有兩個(gè)回調(diào) 一個(gè)是成功后的方法 另一個(gè)是失敗后的方法
 *    根據(jù)成功或失敗的狀態(tài)去執(zhí)行相關(guān)成功onFilfulled()或者失敗onRejected()的回調(diào)方法
 */
Promise.prototype.then = function(onFilfulled,onRejected){
    let that = this;
    if(that.status === "resolved"){
        /** 7 如果狀態(tài)已經(jīng)變更為resolved 
         *    說(shuō)明resolve方法已經(jīng)被調(diào)用
         *    那么此時(shí)就執(zhí)行成功的回調(diào)函數(shù)onFilfulled
         *    并傳入?yún)?shù) that.value
         * */
        onFilfulled(that.value);
    }
    if(that.status === "rejected"){
        /** 8 同上
         *    傳入?yún)?shù) that.reason
         */
        onRejected(that.reason);
    }
}

module.exports = Promise;

通過(guò)require()引入手?jǐn)]的Promise

let Promise = require("./myPromise");

let p1 = ()=>{
    return new Promise((resolve,reject)=>{
        resolve("success.1");
    });
}

p1().then((data)=>{
    console.log(data); // 打印 success.1
},(err)=>{
    console.log(err);
});

ok.經(jīng)調(diào)用發(fā)現(xiàn) 此代碼可以實(shí)現(xiàn)部分Promise的功能,但僅僅是同步下才有效果。
那異步呢? 別急這就來(lái)~:

增加異步功能

注意觀看序號(hào) 1 2 3 4 5 ...


function Promise(executor){
    let that = this;
    that.status = "pending";
    that.value = null;
    that.reason = null;
    /** 1 因?yàn)楫惒讲皇橇⒓磮?zhí)行 狀態(tài)不會(huì)變更 成功或失敗的回調(diào)函數(shù)也不會(huì)執(zhí)行
     *    所以先定義好存放成功或失敗回調(diào)函數(shù)的數(shù)組 
     *    以便將成功或失敗的回調(diào)函數(shù)先保存起來(lái)
     * */
    that.onFilFulledCallbacks = [];
    that.onRejectedCallbacks = [];

    function resolve(value){
        if(that.status === "pending"){
            that.status = "resolved";
            that.value = value;
            /** 3 發(fā)布
             *    等待狀態(tài)發(fā)生變更
             *    狀態(tài)變更后 立即執(zhí)行之前存放在相應(yīng)數(shù)組中所有的成功或失敗的回調(diào)函數(shù)
             *    即 發(fā)布
             */
            that.onFilFulledCallbacks.forEach((fn)=>{
                fn();
            });
        }
    }
    function reject(reason){
        if(that.status === "pending"){
            that.status = "rejected";
            that.reason = reason;
            /** 4 同上 */
            that.onRejectedCallbacks.forEach((fn)=>{
                fn();
            });
        }
    }
    executor(resolve,reject);
}

Promise.prototype.then = function(onFilfulled,onRejected){
    let that = this;
    if(that.status === "resolved"){
        onFilfulled(that.value);
    }
    if(that.status === "rejected"){
        onRejected(that.reason);
    }
    /** 2 訂閱
     *    因?yàn)槭钱惒?狀態(tài)當(dāng)時(shí)并沒(méi)有立即變更 所以狀態(tài)還是pending
     *    此時(shí)需要把成功或者失敗的回調(diào)函數(shù)存放到對(duì)應(yīng)的數(shù)組中
     *    等待狀態(tài)變更時(shí) 再?gòu)臄?shù)組中拿出來(lái)去執(zhí)行
     *    即 訂閱
     *    *存放數(shù)組時(shí) 為了執(zhí)行時(shí)方便 需要把回調(diào)函數(shù)的外層包裹一層空函數(shù)
     */
    if(that.status === "pending"){
        that.onFilFulledCallbacks.push(function(){
            onFilfulled(that.value);
        });
    }
    if(that.status === "pending"){
        that.onRejectedCallbacks.push(function(){
            onRejected(that.reason);
        });
    }
}

module.exports = Promise;

代碼測(cè)試:

let Promise = require("./myPromise");

let p1 = ()=>{
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve("success.1");
            // reject("fail.");
        },1500);
    });
}

p1().then((data)=>{
    console.log(data); // success.1
},(err)=>{
    console.log(err);
});

可以看到 1.5s后 執(zhí)行了resolve() 并打印了success.1,至此,我們實(shí)現(xiàn)了異步的Promise.其實(shí)這里的實(shí)現(xiàn)異步的思想就是發(fā)布訂閱.

en~ok.高能預(yù)警

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

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

相關(guān)文章

  • 手寫(xiě)一個(gè)符合A+規(guī)范Promise

    摘要:本文同時(shí)也發(fā)布在我的博客上,歡迎之前也手寫(xiě)過(guò)簡(jiǎn)單的,這次則是為了通過(guò)官方的測(cè)試集,借鑒了一些下載量較多的,改了幾遍,終于是通過(guò)了規(guī)范的個(gè)測(cè)試用例如何測(cè)試測(cè)試庫(kù)地址在這,大家在寫(xiě)完自己的后,不妨也去測(cè)試一下,檢驗(yàn)自己的是否符合規(guī)范。 本文同時(shí)也發(fā)布在我的github博客上,歡迎star~ 之前也手寫(xiě)過(guò)簡(jiǎn)單的promise,這次則是為了通過(guò)官方的Promise A+測(cè)試集,借鑒了一些下載量...

    jsummer 評(píng)論0 收藏0
  • promise/A+規(guī)范翻譯以及手寫(xiě)實(shí)現(xiàn)

    摘要:如果實(shí)現(xiàn)滿足所有要求,則實(shí)現(xiàn)可能允許。本條款允許使用特定于實(shí)現(xiàn)的方法來(lái)采用已知一致承諾的狀態(tài)。接下來(lái)根據(jù)規(guī)范進(jìn)行手寫(xiě)實(shí)現(xiàn)注釋偷懶就將對(duì)應(yīng)的規(guī)范標(biāo)注出來(lái),其實(shí)基本上就是對(duì)著規(guī)范實(shí)現(xiàn)。 如果要手寫(xiě)實(shí)現(xiàn)promise,那么先看看promise/A+規(guī)范,再來(lái)實(shí)現(xiàn),將會(huì)事半功倍。那么我先翻譯一下Promise/A+規(guī)范中的內(nèi)容。 術(shù)語(yǔ) 1.1 promise 是一個(gè)帶有符合此規(guī)范的the...

    LiuZh 評(píng)論0 收藏0
  • 手寫(xiě)一個(gè)符合promise/A+規(guī)范promise庫(kù)

    摘要:使用及原理分析通過(guò)關(guān)鍵字創(chuàng)建實(shí)例接受一個(gè)參數(shù)方法返回兩個(gè)方法可用通過(guò)在方法中通過(guò)調(diào)用使成功或調(diào)用使失敗來(lái)控制狀態(tài)中可以執(zhí)行同步代碼也可以執(zhí)行異步代碼原型對(duì)象上有方法供實(shí)例調(diào)用方法接受兩個(gè)參數(shù)默認(rèn)為一個(gè)函數(shù)默認(rèn)為一個(gè)函數(shù)當(dāng)狀態(tài)為時(shí)執(zhí)行用戶(hù)傳入 promise使用及原理分析: 通過(guò)new關(guān)鍵字創(chuàng)建promise實(shí)例, 接受一個(gè)executor參數(shù), executor方法返回兩個(gè)方法 res...

    venmos 評(píng)論0 收藏0
  • 異步發(fā)展流程 —— 手寫(xiě)一個(gè)符合 Promise/A+ 規(guī)范 Promise

    摘要:構(gòu)造函數(shù)的實(shí)現(xiàn)我們?cè)谑褂玫臅r(shí)候其實(shí)是使用關(guān)鍵字創(chuàng)建了一個(gè)的實(shí)例,其實(shí)是一個(gè)類(lèi),即構(gòu)造函數(shù),下面來(lái)實(shí)現(xiàn)構(gòu)造函數(shù)。 showImg(https://segmentfault.com/img/remote/1460000018998456); 閱讀原文 概述 Promise 是 js 異步編程的一種解決方案,避免了 回調(diào)地獄 給編程帶來(lái)的麻煩,在 ES6 中成為了標(biāo)準(zhǔn),這篇文章重點(diǎn)不是敘...

    UnixAgain 評(píng)論0 收藏0
  • JavaScript之手寫(xiě)Promise

    摘要:如果狀態(tài)是等待態(tài)的話,就往回調(diào)函數(shù)中函數(shù),比如如下代碼就會(huì)進(jìn)入等待態(tài)的邏輯以上就是簡(jiǎn)單版實(shí)現(xiàn)實(shí)現(xiàn)一個(gè)符合規(guī)范的接下來(lái)大部分代碼都是根據(jù)規(guī)范去實(shí)現(xiàn)的。 為更好的理解, 推薦閱讀Promise/A+ 規(guī)范 實(shí)現(xiàn)一個(gè)簡(jiǎn)易版 Promise 在完成符合 Promise/A+ 規(guī)范的代碼之前,我們可以先來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)易版 Promise,因?yàn)樵诿嬖囍?,如果你能?shí)現(xiàn)出一個(gè)簡(jiǎn)易版的 Promise ...

    stefan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

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