10分鐘手寫一個Promise

不要被then需要異步執(zhí)行嚇到了擎椰,then傳入的是個函數(shù)膨桥,什么時候調(diào)用创葡,應(yīng)該由第一次回調(diào)決定
靜態(tài)的all浙踢、race等方法,后面再補充

function promise(func){
    this.state = 'pending'; //狀態(tài)
    this.resolveArg; //回調(diào)參數(shù)灿渴,下同
    this.rejectArg;
    this.thenQueue = []; //調(diào)用隊列
    this.thenable = true;

    this.resolveFunc = _resolveFunc.bind(this);
    this.rejectFunc  = _rejectFunc.bind(this);
    this.catchFunc   = _catchFunc.bind(this);
    //將 res洛波,rej回調(diào)傳入作用域內(nèi)并執(zhí)行主函數(shù)
    try {
        func(this.resolveFunc,this.rejectFunc)
    } catch (e) {
        this.catchFunc(e);
    }
}
promise.prototype = {
    constructor : promise,//綁定構(gòu)造器
    /* 調(diào)用then,只需要把傳入的回調(diào)壓進then隊列里即可骚露,不需要timeout操作*/
    then : function(res,rej) {
        if (!this.thenable) {
            return this;
        }
        //
        this.thenQueue.push({
            res : res,
            rej : rej
        })
        return this;
    },
    catch: function(func) {
        this.catchFunc = func;
        return this
    },
    finally: function (func) {
        this.finallyFunc = func;
        this.thenable = false;
        return this;
    }
}
/* rej蹬挤、res回調(diào)會將then隊列里的函數(shù)依次執(zhí)行,并且上一個then的返回值作為下一個then的參數(shù) */
function _rejectFunc (args) {
    this.rejectArg = args;
    this.state     = 'rejected'
    if(!this.thenQueue.length){return;}
    while (this.thenQueue.length) {
        rejCallback = this.thenQueue.shift().rej;
        try {
            var newReturns = rejCallback(this.rejectArg);
            this.rejectArg = newReturns;
        } catch (e) {
            this.catchFunc(e)
        }
    }
    this.finallyFunc && this.finallyFunc();
    this.thenable = false;
}

function _resolveFunc (args) {
    this.resolveArg = args;
    this.state      = 'fullfilled'
    if(!this.thenQueue.length){return;}
    while (this.thenQueue.length) {
        resCallback = this.thenQueue.shift().res;
        try {
            var newReturns  = resCallback(this.resolveArg)
            this.resolveArg = newReturns;
        } catch(e) {
            this.catchFunc(e)
        }
    }
    this.finallyFunc && this.finallyFunc();
    this.thenable = false;
}
function _catchFunc (e){
    throw Error('Uncaught promise error:' + e)
}
new promise(res=>{
    setTimeout(()=>{
        res([123])
    },1000)
}).then(res=>{
    console.log('res',res)
    return 'bbb'
}).then(res=>{
    console.log(res)
})

存在的問題

Promise.then是在下一個MicroTask調(diào)用的棘幸,而上述的代碼是同步執(zhí)行

new promise(res=>{
  setTimeout(()=>{
    res()
  })
  console.log('搶先一步')
}).then()

設(shè)置了setTimeout會使then在MacroTask之后調(diào)用
Node.js中可以使用setImmediate焰扳,就能使其真正的在下一個MicroTask執(zhí)行

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市误续,隨后出現(xiàn)的幾起案子吨悍,更是在濱河造成了極大的恐慌,老刑警劉巖蹋嵌,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件畜份,死亡現(xiàn)場離奇詭異,居然都是意外死亡欣尼,警方通過查閱死者的電腦和手機爆雹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來愕鼓,“玉大人钙态,你說我怎么就攤上這事」交危” “怎么了册倒?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長磺送。 經(jīng)常有香客問我驻子,道長灿意,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任崇呵,我火速辦了婚禮缤剧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘域慷。我一直安慰自己荒辕,他們只是感情好,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布犹褒。 她就那樣靜靜地躺著抵窒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪叠骑。 梳的紋絲不亂的頭發(fā)上李皇,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天,我揣著相機與錄音宙枷,去河邊找鬼疙赠。 笑死,一個胖子當著我的面吹牛朦拖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播厌衔,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼璧帝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了富寿?” 一聲冷哼從身側(cè)響起睬隶,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎页徐,沒想到半個月后苏潜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡变勇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年恤左,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搀绣。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡飞袋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出链患,到底是詐尸還是另有隱情巧鸭,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布麻捻,位于F島的核電站纲仍,受9級特大地震影響呀袱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜郑叠,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一夜赵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧锻拘,春花似錦油吭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至推穷,卻和暖如春心包,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背馒铃。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工蟹腾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人区宇。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓娃殖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親议谷。 傳聞我的和親對象是個殘疾皇子炉爆,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351