part1整理

  1. 函數(shù)式編程:
    JavaScript函數(shù)式編程指南

  2. 異步編程:
    異步編程

  3. Promise源碼

const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

function MyPromise(fn) {
    const _self = this;
    this.value = undefined;
    this.reason = undefined;
    this.status = PENDING;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    function resolve(value) {
        // if (value instanceof MyPromise) {
        //     return value.then(resolve, reject);
        // }
        if (_self.status === PENDING) {
            setTimeout(() => {
                _self.status = FULFILLED;
                _self.value = value;
                _self.onFulfilledCallbacks.forEach(callback => callback(_self.value));
            }, 0)
        }
    }

    function reject(reason) {
        if (_self.status === PENDING) {
            setTimeout(function() {
                _self.status = REJECTED;
                _self.reason = reason;
                _self.onRejectedCallbacks.forEach(callback => callback(_self.reason));
            }, 0)
        }
    }
    try {
        fn(resolve, reject);
    } catch (e) {
        reject(e);
    }
}

// 用來(lái)解析回調(diào)函數(shù)的返回值x惰聂,x可能是普通值也可能是個(gè)promise對(duì)象
function resolvePromise(bridgepromise, x, resolve, reject) {
    // 2.3.1規(guī)范宠漩,避免循環(huán)引用
    if (bridgepromise === x) {
        return reject(new TypeError('Circular reference'));
    }

    let called = false; // 只允許調(diào)用一次resolve/reject,以第一次為準(zhǔn)
    // 2.3.3規(guī)范,如果 x 為對(duì)象或者函數(shù)
    if (x != null && ((typeof x === 'object') || (typeof x === 'function'))) {
        try {
            // 是否是thenable對(duì)象(具有then方法的對(duì)象/函數(shù))
            //2.3.3.1 將 then 賦為 x.then
            let then = x.then; // 如果then具有g(shù)etter屬性预吆,此時(shí)獲取會(huì)發(fā)生異常
            if (typeof then === 'function') {
                // 2.3.3.3 如果 then 是一個(gè)函數(shù),以x為this調(diào)用then函數(shù)啦鸣,且第一個(gè)參數(shù)是resolvePromise涣狗,第二個(gè)參數(shù)是rejectPromise
                then.call(x, y => {
                    if (called) return;
                    called = true;
                    // 一直解析,直到結(jié)果為常量為止
                    resolvePromise(bridgepromise, y, resolve, reject);
                }, error => {
                    if (called) return;
                    called = true;
                    reject(error);
                })
            } else { // 是一個(gè)普通對(duì)象
                // 2.3.3.4 如果 then不是一個(gè)函數(shù)更啄,則 以x為值fulfill promise稚疹。
                resolve(x);
            }
        } catch (e) {
            // 2.3.3.2 如果在取x.then值時(shí)拋出了異常,則以這個(gè)異常做為原因?qū)romise拒絕祭务。
            if (called) return;
            called = true;
            reject(e);
        }
    } else { // 普通值内狗,直接返回即可
        // 如果x是一個(gè)普通值怪嫌,就讓bridgePromise的狀態(tài)fulfilled,并把這個(gè)值傳遞下去
        resolve(x);
    }
}

MyPromise.prototype.then = function(onFulfilled, onRejected) {
    const _self = this;
    let bridgePromise;
    //防止使用者不傳成功或失敗回調(diào)函數(shù)柳沙,所以成功失敗回調(diào)都給了默認(rèn)回調(diào)函數(shù)
    // 值的穿透?jìng)鬟f
    onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value;
    onRejected = typeof onRejected === "function" ? onRejected : error => { throw error };
    if (this.status === FULFILLED) {
        return bridgePromise = new MyPromise((resolve, reject) => {
            setTimeout(() => { // 因?yàn)閚ew過(guò)程中還未拿到bridgePromise岩灭,所以這里走異步,以拿到promise2
                try {
                    // 函數(shù)返回值
                    let x = onFulfilled(_self.value);
                    resolvePromise(bridgePromise, x, resolve, reject);
                } catch (e) {
                    reject(e); // 如果執(zhí)行函數(shù)時(shí)拋出失敗赂鲤,那么會(huì)走向下一個(gè)失敗狀態(tài)
                }
            }, 0);
        })
    }
    if (this.status === REJECTED) {
        return bridgePromise = new MyPromise((resolve, reject) => {
            setTimeout(() => {
                try {
                    let x = onRejected(_self.reason);
                    resolvePromise(bridgePromise, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            }, 0);
        });
    }
    if (this.status === PENDING) {
        return bridgePromise = new MyPromise((resolve, reject) => {
            _self.onFulfilledCallbacks.push((value) => {
                try {
                    let x = onFulfilled(value);
                    resolvePromise(bridgePromise, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            });
            _self.onRejectedCallbacks.push((reason) => {
                try {
                    let x = onRejected(reason);
                    resolvePromise(bridgePromise, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            });
        });
    }
}

//catch方法其實(shí)是個(gè)語(yǔ)法糖噪径,就是只傳onRejected不傳onFulfilled的then方法
MyPromise.prototype.catch = function(onRejected) {
    return this.then(null, onRejected);
}

MyPromise.prototype.finally = function(callback) {
    return this.then(value => {
        return MyPromise.resolve(callback()).then(() => value)
    }, reason => {
        return MyPromise.resolve(callback()).then(() => { throw reason })
    })
}

MyPromise.all = function(promises) {
    let result = [];
    let count = 0;

    return new MyPromise(function(resolve, reject) {
        function addData(key, value) {
            result[key] = value
            count++
            if (count === promises.length) {
                resolve(result)
            }
        }
        for (let i = 0; i < promises.length; i++) {
            let current = promises[i]
            if (current instanceof MyPromise) {
                current.then(value => addData(i, value), reason => reject(reason))
            } else {
                addData(i, promises[i])
            }
        }

    });
}

MyPromise.race = function(promises) {
    return new MyPromise(function(resolve, reject) {
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(function(data) {
                resolve(data);
            }, function(error) {
                reject(error);
            });
        }
    });
}

MyPromise.resolve = function(value) {
    if (value instanceof MyPromise) return value
    return new MyPromise(resolve => {
        resolve(value);
    });
}

MyPromise.reject = function(error) {
    if (value instanceof MyPromise) return error
    return new MyPromise((resolve, reject) => {
        reject(error);
    });
}

MyPromise.promisify = function(fn) {
    return function() {
        var args = Array.from(arguments);
        return new MyPromise(function(resolve, reject) {
            fn.apply(null, args.concat(function(err) {
                err ? reject(err) : resolve(arguments[1])
            }));
        })
    }
}

// 執(zhí)行測(cè)試用例需要用到的代碼
MyPromise.deferred = function() {
    let defer = {};
    defer.promise = new MyPromise((resolve, reject) => {
        defer.resolve = resolve;
        defer.reject = reject;
    });
    return defer;
}
  1. JavaScript基礎(chǔ)知識(shí)
    ES2015+疑難點(diǎn)解析
    你不知道的JS系列:
    徹底搞懂JavaScript函數(shù)執(zhí)行機(jī)制
    徹底搞懂JavaScript作用域
    徹底搞懂JavaScript之對(duì)象
    徹底搞懂JavaScript之類
    徹底搞懂JavaScript之原型
    徹底搞懂JavaScript中的this
    徹底搞懂JavaScript數(shù)據(jù)類型
    JavaScript類型轉(zhuǎn)換
    JavaScript語(yǔ)句

  2. TypeScript疑難點(diǎn)
    TypeScript疑難解析

  1. JavaScript性能優(yōu)化
    JavaScript性能優(yōu)化
    JS垃圾回收詳解
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市数初,隨后出現(xiàn)的幾起案子找爱,更是在濱河造成了極大的恐慌,老刑警劉巖泡孩,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件车摄,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡珍德,警方通過(guò)查閱死者的電腦和手機(jī)练般,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)锈候,“玉大人薄料,你說(shuō)我怎么就攤上這事”昧眨” “怎么了摄职?”我有些...
    開(kāi)封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)获列。 經(jīng)常有香客問(wèn)我谷市,道長(zhǎng),這世上最難降的妖魔是什么击孩? 我笑而不...
    開(kāi)封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任迫悠,我火速辦了婚禮,結(jié)果婚禮上巩梢,老公的妹妹穿的比我還像新娘创泄。我一直安慰自己,他們只是感情好括蝠,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布鞠抑。 她就那樣靜靜地躺著,像睡著了一般忌警。 火紅的嫁衣襯著肌膚如雪搁拙。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音箕速,去河邊找鬼酪碘。 笑死,一個(gè)胖子當(dāng)著我的面吹牛盐茎,可吹牛的內(nèi)容都是我干的婆跑。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼庭呜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼滑进!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起募谎,我...
    開(kāi)封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤扶关,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后数冬,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體节槐,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年拐纱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了铜异。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡秸架,死狀恐怖揍庄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情东抹,我是刑警寧澤蚂子,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站缭黔,受9級(jí)特大地震影響食茎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜馏谨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一别渔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惧互,春花似錦哎媚、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)艘刚。三九已至管宵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背箩朴。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工岗喉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人炸庞。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓钱床,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親埠居。 傳聞我的和親對(duì)象是個(gè)殘疾皇子查牌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345