成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

只會(huì)用就out了,手寫一個(gè)符合規(guī)范的Promise

muzhuyu / 1684人閱讀

摘要:傳入的回調(diào)函數(shù)也不是一個(gè)函數(shù)類型,那怎么辦規(guī)范中說(shuō)忽略它就好了。因此需要判斷一下回調(diào)函數(shù)的類型,如果明確是個(gè)函數(shù)再執(zhí)行它。

Promise是什么

所謂Promise,簡(jiǎn)單說(shuō)就是一個(gè)容器,里面保存著某個(gè)未來(lái)才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果。從語(yǔ)法上說(shuō),Promise 是一個(gè)對(duì)象,從它可以獲取異步操作的消息。Promise 提供統(tǒng)一的 API,各種異步操作都可以用同樣的方法進(jìn)行處理。

Promise是處理異步編碼的一個(gè)解決方案,在Promise出現(xiàn)以前,異步代碼的編寫都是通過(guò)回調(diào)函數(shù)來(lái)處理的,回調(diào)函數(shù)本身沒(méi)有任何問(wèn)題,只是當(dāng)多次異步回調(diào)有邏輯關(guān)系時(shí)就會(huì)變得復(fù)雜:

const fs = require("fs");
fs.readFile("1.txt", (err,data) => {
    fs.readFile("2.txt", (err,data) => {
        fs.readFile("3.txt", (err,data) => {
            //可能還有后續(xù)代碼
        });
    });
});

上面讀取了3個(gè)文件,它們是層層遞進(jìn)的關(guān)系,可以看到多個(gè)異步代碼套在一起不是縱向發(fā)展的,而是橫向,不論是從語(yǔ)法上還是從排錯(cuò)上都不好,于是Promise的出現(xiàn)可以解決這一痛點(diǎn)。

上述代碼如果改寫成Promise版是這樣:

const util = require("util");
const fs = require("fs");
const readFile = util.promisify(fs.readFile);

readFile("1.txt")
    .then(data => {
        return readFile("2.txt");
    }).then(data => {
        return readFile("3.txt");
    }).then(data => {
        //...
    });

可以看到,代碼是從上至下縱向發(fā)展了,更加符合人們的邏輯。

下面手寫一個(gè)Promise,按照Promises/A+規(guī)范,可以參照規(guī)范原文:
Promises/A+規(guī)范

手寫實(shí)現(xiàn)Promise是一道前端經(jīng)典的面試題,比如美團(tuán)的面試就是必考題,Promise的邏輯還是比較復(fù)雜的,考慮的邏輯也比較多,下面總結(jié)手寫Promise的關(guān)鍵點(diǎn),和怎樣使用代碼來(lái)實(shí)現(xiàn)它。

Promise代碼基本結(jié)構(gòu)

實(shí)例化Promise對(duì)象時(shí)傳入一個(gè)函數(shù)作為執(zhí)行器,有兩個(gè)參數(shù)(resolve和reject)分別將結(jié)果變?yōu)槌晒B(tài)和失敗態(tài)。我們可以寫出基本結(jié)構(gòu)

function Promise(executor) {
    this.state = "pending"; //狀態(tài)
    this.value = undefined; //成功結(jié)果
    this.reason = undefined; //失敗原因

    function resolve(value) {
        
    }

    function reject(reason) {

    }
}

module.exports = Promise;

其中state屬性保存了Promise對(duì)象的狀態(tài),規(guī)范中指明,一個(gè)Promise對(duì)象只有三種狀態(tài):等待態(tài)(pending)成功態(tài)(resolved)和失敗態(tài)(rejected)。
當(dāng)一個(gè)Promise對(duì)象執(zhí)行成功了要有一個(gè)結(jié)果,它使用value屬性保存;也有可能由于某種原因失敗了,這個(gè)失敗原因放在reason屬性中保存。

then方法定義在原型上

每一個(gè)Promise實(shí)例都有一個(gè)then方法,它用來(lái)處理異步返回的結(jié)果,它是定義在原型上的方法,我們先寫一個(gè)空方法做好準(zhǔn)備:

Promise.prototype.then = function (onFulfilled, onRejected) {
};
當(dāng)實(shí)例化Promise時(shí)會(huì)立即執(zhí)行

當(dāng)我們自己實(shí)例化一個(gè)Promise時(shí),其執(zhí)行器函數(shù)(executor)會(huì)立即執(zhí)行,這是一定的:

let p = new Promise((resolve, reject) => {
    console.log("執(zhí)行了");
});

運(yùn)行結(jié)果:

執(zhí)行了

因此,當(dāng)實(shí)例化Promise時(shí),構(gòu)造函數(shù)中就要馬上調(diào)用傳入的executor函數(shù)執(zhí)行

function Promise(executor) {
    var _this = this;
    this.state = "pending";
    this.value = undefined;
    this.reason = undefined;

    executor(resolve, reject); //馬上執(zhí)行
    
    function resolve(value) {}
    function reject(reason) {}
}
已經(jīng)是成功態(tài)或是失敗態(tài)不可再更新?tīng)顟B(tài)

規(guī)范中規(guī)定,當(dāng)Promise對(duì)象已經(jīng)由pending狀態(tài)改變?yōu)榱顺晒B(tài)(resolved)或是失敗態(tài)(rejected)就不能再次更改狀態(tài)了。因此我們?cè)诟聽(tīng)顟B(tài)時(shí)要判斷,如果當(dāng)前狀態(tài)是pending(等待態(tài))才可更新:

    function resolve(value) {
        //當(dāng)狀態(tài)為pending時(shí)再做更新
        if (_this.state === "pending") {
            _this.value = value;//保存成功結(jié)果
            _this.state = "resolved";
        }

    }

    function reject(reason) {
    //當(dāng)狀態(tài)為pending時(shí)再做更新
        if (_this.state === "pending") {
            _this.reason = reason;//保存失敗原因
            _this.state = "rejected";
        }
    }

以上可以看到,在resolve和reject函數(shù)中分別加入了判斷,只有當(dāng)前狀態(tài)是pending才可進(jìn)行操作,同時(shí)將成功的結(jié)果和失敗的原因都保存到對(duì)應(yīng)的屬性上。之后將state屬性置為更新后的狀態(tài)。

then方法的基本實(shí)現(xiàn)

當(dāng)Promise的狀態(tài)發(fā)生了改變,不論是成功或是失敗都會(huì)調(diào)用then方法,所以,then方法的實(shí)現(xiàn)也很簡(jiǎn)單,根據(jù)state狀態(tài)來(lái)調(diào)用不同的回調(diào)函數(shù)即可:

Promise.prototype.then = function (onFulfilled, onRejected) {
    if (this.state === "resolved") {
        //判斷參數(shù)類型,是函數(shù)執(zhí)行之
        if (typeof onFulfilled === "function") {
            onFulfilled(this.value);
        }

    }
    if (this.state === "rejected") {
        if (typeof onRejected === "function") {
            onRejected(this.reason);
        }
    }
};

需要一點(diǎn)注意,規(guī)范中說(shuō)明了,onFulfilled 和 onRejected 都是可選參數(shù),也就是說(shuō)可以傳也可以不傳。傳入的回調(diào)函數(shù)也不是一個(gè)函數(shù)類型,那怎么辦?規(guī)范中說(shuō)忽略它就好了。因此需要判斷一下回調(diào)函數(shù)的類型,如果明確是個(gè)函數(shù)再執(zhí)行它。

讓Promise支持異步

代碼寫到這里似乎基本功能都實(shí)現(xiàn)了,可是還有一個(gè)很大的問(wèn)題,目前此Promise還不支持異步代碼,如果Promise中封裝的是異步操作,then方法無(wú)能為力:

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(1);
    },500);
});

p.then(data => console.log(data)); //沒(méi)有任何結(jié)果

運(yùn)行以上代碼發(fā)現(xiàn)沒(méi)有任何結(jié)果,本意是等500毫秒后執(zhí)行then方法,哪里有問(wèn)題呢?原因是setTimeout函數(shù)使得resolve是異步執(zhí)行的,有延遲,當(dāng)調(diào)用then方法的時(shí)候,此時(shí)此刻的狀態(tài)還是等待態(tài)(pending),因此then方法即沒(méi)有調(diào)用onFulfilled也沒(méi)有調(diào)用onRejected。

這個(gè)問(wèn)題如何解決?我們可以參照發(fā)布訂閱模式,在執(zhí)行then方法時(shí)如果還在等待態(tài)(pending),就把回調(diào)函數(shù)臨時(shí)寄存到一個(gè)數(shù)組里,當(dāng)狀態(tài)發(fā)生改變時(shí)依次從數(shù)組中取出執(zhí)行就好了,清楚這個(gè)思路我們實(shí)現(xiàn)它,首先在類上新增兩個(gè)Array類型的數(shù)組,用于存放回調(diào)函數(shù):

function Promise(executor) {
    var _this = this;
    this.state = "pending";
    this.value = undefined;
    this.reason = undefined;
    this.onFulfilledFunc = [];//保存成功回調(diào)
    this.onRejectedFunc = [];//保存失敗回調(diào)
    //其它代碼略...
}

這樣當(dāng)then方法執(zhí)行時(shí),若狀態(tài)還在等待態(tài)(pending),將回調(diào)函數(shù)依次放入數(shù)組中:

Promise.prototype.then = function (onFulfilled, onRejected) {
    //等待態(tài),此時(shí)異步代碼還沒(méi)有走完
    if (this.state === "pending") {
        if (typeof onFulfilled === "function") {
            this.onFulfilledFunc.push(onFulfilled);//保存回調(diào)
        }
        if (typeof onRejected === "function") {
            this.onRejectedFunc.push(onRejected);//保存回調(diào)
        }
    }
    //其它代碼略...
};

寄存好了回調(diào),接下來(lái)就是當(dāng)狀態(tài)改變時(shí)執(zhí)行就好了:

    function resolve(value) {
        if (_this.state === "pending") {
            _this.value = value;
            //依次執(zhí)行成功回調(diào)
            _this.onFulfilledFunc.forEach(fn => fn(value));
            _this.state = "resolved";
        }

    }

    function reject(reason) {
        if (_this.state === "pending") {
            _this.reason = reason;
            //依次執(zhí)行失敗回調(diào)
            _this.onRejectedFunc.forEach(fn => fn(reason));
            _this.state = "rejected";
        }
    }

至此,Promise已經(jīng)支持了異步操作,setTimeout延遲后也可正確執(zhí)行then方法返回結(jié)果。

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

Promise處理異步代碼最強(qiáng)大的地方就是支持鏈?zhǔn)秸{(diào)用,這塊也是最復(fù)雜的,我們先梳理一下規(guī)范中是怎么定義的:

每個(gè)then方法都返回一個(gè)新的Promise對(duì)象(原理的核心

如果then方法中顯示地返回了一個(gè)Promise對(duì)象就以此對(duì)象為準(zhǔn),返回它的結(jié)果

如果then方法中返回的是一個(gè)普通值(如Number、String等)就使用此值包裝成一個(gè)新的Promise對(duì)象返回。

如果then方法中沒(méi)有return語(yǔ)句,就視為返回一個(gè)用Undefined包裝的Promise對(duì)象

若then方法中出現(xiàn)異常,則調(diào)用失敗態(tài)方法(reject)跳轉(zhuǎn)到下一個(gè)then的onRejected

如果then方法沒(méi)有傳入任何回調(diào),則繼續(xù)向下傳遞(值的傳遞特性)。

規(guī)范中說(shuō)的很抽像,我們可以把不好理解的點(diǎn)使用代碼演示一下。

其中第3項(xiàng),如果返回是個(gè)普通值就使用它包裝成Promise,我們用代碼來(lái)演示:

let p =new Promise((resolve,reject)=>{
    resolve(1);
});

p.then(data=>{
    return 2; //返回一個(gè)普通值
}).then(data=>{
    console.log(data); //輸出2
});

可見(jiàn),當(dāng)then返回了一個(gè)普通的值時(shí),下一個(gè)then的成功態(tài)回調(diào)中即可取到上一個(gè)then的返回結(jié)果,說(shuō)明了上一個(gè)then正是使用2來(lái)包裝成的Promise,這符合規(guī)范中說(shuō)的。

第4項(xiàng),如果then方法中沒(méi)有return語(yǔ)句,就視為返回一個(gè)用Undefined包裝的Promise對(duì)象

let p = new Promise((resolve, reject) => {
    resolve(1);
});

p.then(data => {
    //沒(méi)有return語(yǔ)句
}).then(data => {
    console.log(data); //undefined
});

可以看到,當(dāng)沒(méi)有返回任何值時(shí)不會(huì)報(bào)錯(cuò),沒(méi)有任何語(yǔ)句時(shí)實(shí)際上就是return undefined;即將undefined包裝成Promise對(duì)象傳給下一個(gè)then的成功態(tài)。

第6項(xiàng),如果then方法沒(méi)有傳入任何回調(diào),則繼續(xù)向下傳遞,這是什么意思呢?這就是Promise中值的穿透,還是用代碼演示一下:

let p = new Promise((resolve, reject) => {
    resolve(1);
});

p.then(data => 2)
.then()
.then()
.then(data => {
    console.log(data); //2
});

以上代碼,在第一個(gè)then方法之后連續(xù)調(diào)用了兩個(gè)空的then方法 ,沒(méi)有傳入任何回調(diào)函數(shù),也沒(méi)有返回值,此時(shí)Promise會(huì)將值一直向下傳遞,直到你接收處理它,這就是所謂的值的穿透。

現(xiàn)在可以明白鏈?zhǔn)秸{(diào)用的原理,不論是何種情況then方法都會(huì)返回一個(gè)Promise對(duì)象,這樣才會(huì)有下個(gè)then方法。

搞清楚了這些點(diǎn),我們就可以動(dòng)手實(shí)現(xiàn)then方法的鏈?zhǔn)秸{(diào)用,一起來(lái)完善它:

Promise.prototype.then = function (onFulfilled, onRejected) {
    var promise2 = new Promise((resolve, reject) => {
    //代碼略...
    }
    return promise2;
};

首先,不論何種情況then都返回Promise對(duì)象,我們就實(shí)例化一個(gè)新promise2并返回。

接下來(lái)就處理根據(jù)上一個(gè)then方法的返回值來(lái)生成新Promise對(duì)象,由于這塊邏輯較復(fù)雜且有很多處調(diào)用,我們抽離出一個(gè)方法來(lái)操作,這也是規(guī)范中說(shuō)明的:

/**
 * 解析then返回值與新Promise對(duì)象
 * @param {Object} promise2 新的Promise對(duì)象 
 * @param {*} x 上一個(gè)then的返回值
 * @param {Function} resolve promise2的resolve
 * @param {Function} reject promise2的reject
 */
function resolvePromise(promise2, x, resolve, reject) {
    //...
}

resolvePromise方法用來(lái)封裝鏈?zhǔn)秸{(diào)用產(chǎn)生的結(jié)果,下面我們分別一個(gè)個(gè)情況的寫出它的邏輯,首先規(guī)范中說(shuō)明,如果promise2x 指向同一對(duì)象,就使用TypeError作為原因轉(zhuǎn)為失敗。原文如下:

If promise and x refer to the same object, reject promise with a TypeError as the reason.

這是什么意思?其實(shí)就是循環(huán)引用,當(dāng)then的返回值與新生成的Promise對(duì)象為同一個(gè)(引用地址相同),則會(huì)拋出TypeError錯(cuò)誤:

let promise2 = p.then(data => {
    return promise2;
});

運(yùn)行結(jié)果:

TypeError: Chaining cycle detected for promise #

很顯然,如果返回了自己的Promise對(duì)象,狀態(tài)永遠(yuǎn)為等待態(tài)(pending),再也無(wú)法成為resolved或是rejected,程序會(huì)死掉,因此首先要處理它:

function resolvePromise(promise2, x, resolve, reject) {
    if (promise2 === x) {
        reject(new TypeError("Promise發(fā)生了循環(huán)引用"));
    }
}

接下來(lái)就是分各種情況處理。當(dāng)x就是一個(gè)Promise,那么就執(zhí)行它,成功即成功,失敗即失敗。若x是一個(gè)對(duì)象或是函數(shù),再進(jìn)一步處理它,否則就是一個(gè)普通值:

function resolvePromise(promise2, x, resolve, reject) {
    if (promise2 === x) {
        reject(new TypeError("Promise發(fā)生了循環(huán)引用"));
    }

    if (x !== null && (typeof x === "object" || typeof x === "function")) {
        //可能是個(gè)對(duì)象或是函數(shù)
    } else {
        //否則是個(gè)普通值
        resolve(x);
    }
}

此時(shí)規(guī)范中說(shuō)明,若是個(gè)對(duì)象,則嘗試將對(duì)象上的then方法取出來(lái),此時(shí)如果報(bào)錯(cuò),那就將promise2轉(zhuǎn)為失敗態(tài)。原文:

If retrieving the property x.then results in a thrown exception e, reject promise with e as the reason.
function resolvePromise(promise2, x, resolve, reject) {
    //代碼略...
    if (x !== null && (typeof x === "object" || typeof x === "function")) {
        //可能是個(gè)對(duì)象或是函數(shù)
        try {
            let then = x.then;//取出then方法引用
        } catch (e) {
            reject(e);
        }
        
    } else {
        //否則是個(gè)普通值
        resolve(x);
    }
}

多說(shuō)幾句,為什么取對(duì)象上的屬性有報(bào)錯(cuò)的可能?Promise有很多實(shí)現(xiàn)(bluebird,Q等),Promises/A+只是一個(gè)規(guī)范,大家都按此規(guī)范來(lái)實(shí)現(xiàn)Promise才有可能通用,因此所有出錯(cuò)的可能都要考慮到,假設(shè)另一個(gè)人實(shí)現(xiàn)的Promise對(duì)象使用Object.defineProperty()惡意的在取值時(shí)拋錯(cuò),我們可以防止代碼出現(xiàn)Bug。

此時(shí),如果對(duì)象中有then,且then是函數(shù)類型,就可以認(rèn)為是一個(gè)Promise對(duì)象,之后,使用x作為this來(lái)調(diào)用then方法。

If then is a function, call it with x as this
//其他代碼略...
if (x !== null && (typeof x === "object" || typeof x === "function")) {
    //可能是個(gè)對(duì)象或是函數(shù)
    try {
        let then = x.then; 
        if (typeof then === "function") {
            //then是function,那么執(zhí)行Promise
            then.call(x, (y) => {
                resolve(y);
            }, (r) => {
                reject(r);
            });
        } else {
            resolve(x);
        }
    } catch (e) {
        reject(e);
    }

} else {
    //否則是個(gè)普通值
    resolve(x);
}

這樣鏈?zhǔn)綄懛ň突就瓿闪?。但是還有一種極端的情況,如果Promise對(duì)象轉(zhuǎn)為成功態(tài)或是失敗時(shí)傳入的還是一個(gè)Promise對(duì)象,此時(shí)應(yīng)該繼續(xù)執(zhí)行,直到最后的Promise執(zhí)行完。

p.then(data => {
    return new Promise((resolve,reject)=>{
        //resolve傳入的還是Promise
        resolve(new Promise((resolve,reject)=>{
            resolve(2);
        }));
    });
})

此時(shí)就要使用遞歸操作了。

規(guī)范中原文如下:

If a promise is resolved with a thenable that participates in a circular thenable chain, such that the recursive nature of [[Resolve]](promise, thenable) eventually causes [[Resolve]](promise, thenable) to be called again, following the above algorithm will lead to infinite recursion. Implementations are encouraged, but not required, to detect such recursion and reject promise with an informative TypeError as the reason.

很簡(jiǎn)單,把調(diào)用resolve改寫成遞歸執(zhí)行resolvePromise方法即可,這樣直到解析Promise成一個(gè)普通值才會(huì)終止,即完成此規(guī)范:

//其他代碼略...
if (x !== null && (typeof x === "object" || typeof x === "function")) {
    //可能是個(gè)對(duì)象或是函數(shù)
    try {
        let then = x.then; 
        if (typeof then === "function") {
            let y = then.call(x, (y) => {
                //遞歸調(diào)用,傳入y若是Promise對(duì)象,繼續(xù)循環(huán)
                resolvePromise(promise2, y, resolve, reject);
            }, (r) => {
                reject(r);
            });
        } else {
            resolve(x);
        }
    } catch (e) {
        reject(e);
    }

} else {
    //是個(gè)普通值,最終結(jié)束遞歸
    resolve(x);
}

到此,鏈?zhǔn)秸{(diào)用的代碼已全部完畢。在相應(yīng)的地方調(diào)用resolvePromise方法即可。

最后的最后

其實(shí),寫到此處Promise的真正源碼已經(jīng)寫完了,但是距離100分還差一分,是什么呢?

規(guī)范中說(shuō)明,Promise的then方法是異步執(zhí)行的。

onFulfilled or onRejected must not be called until the execution context stack contains only platform code.

ES6的原生Promise對(duì)象已經(jīng)實(shí)現(xiàn)了這一點(diǎn),但是我們自己的代碼是同步執(zhí)行,不相信可以試一下,那么如何將同步代碼變成異步執(zhí)行呢?可以使用setTimeout函數(shù)來(lái)模擬一下:

setTimeout(()=>{
    //此處的代碼會(huì)異步執(zhí)行
},0);

利用此技巧,將代碼then執(zhí)行處的所有地方使用setTimeout變?yōu)楫惒郊纯?,舉個(gè)栗子:

setTimeout(() => {
    try {
        let x = onFulfilled(value);
        resolvePromise(promise2, x, resolve, reject);
    } catch (e) {
        reject(e);
    }
},0);

好了,現(xiàn)在已經(jīng)是滿分的Promise源碼了。

滿分的測(cè)試

好不容易寫好的Promise源碼,最終是否真的符合Promises/A+規(guī)范,開(kāi)源社區(qū)提供了一個(gè)包用于測(cè)試我們的代碼:promises-aplus-tests

這個(gè)包的使用方法不在詳述,此包可以一項(xiàng)項(xiàng)的檢查我們寫的代碼是否合規(guī),如果有任一項(xiàng)不符就會(huì)給我們報(bào)出來(lái),如果檢查你的代碼一路都是綠色,那恭喜,你的Proimse已經(jīng)合法了,可以上線提供給別人使用了:

872項(xiàng)測(cè)試通過(guò)!

現(xiàn)在源碼都會(huì)寫,終于可以自信的回答面試官的問(wèn)題了。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/97213.html

相關(guān)文章

  • promise/A+規(guī)范翻譯以及手寫實(shí)現(xiàn)

    摘要:如果實(shí)現(xiàn)滿足所有要求,則實(shí)現(xiàn)可能允許。本條款允許使用特定于實(shí)現(xiàn)的方法來(lái)采用已知一致承諾的狀態(tài)。接下來(lái)根據(jù)規(guī)范進(jìn)行手寫實(shí)現(xiàn)注釋偷懶就將對(duì)應(yīng)的規(guī)范標(biāo)注出來(lái),其實(shí)基本上就是對(duì)著規(guī)范實(shí)現(xiàn)。 如果要手寫實(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
  • 一步一步實(shí)現(xiàn)一個(gè)符合PromiseA+規(guī)范Promise庫(kù)(1)

    摘要:今天我們來(lái)自己手寫一個(gè)符合規(guī)范的庫(kù)。是異步編程的一種解決方案,比傳統(tǒng)的解決方案回調(diào)函數(shù)和事件更合理和更強(qiáng)大。我們可以看到,其實(shí)就是一個(gè)構(gòu)造函數(shù)。所以說(shuō)我們的數(shù)組里存的是一個(gè)一個(gè)的的回調(diào)函數(shù),也就是一個(gè)一個(gè)。 今天我們來(lái)自己手寫一個(gè)符合PromiseA+規(guī)范的Promise庫(kù)。大家是不是很激動(dòng)呢?? showImg(https://segmentfault.com/img/bV6t4Z?...

    joyvw 評(píng)論0 收藏0
  • 手寫一款符合Promise/A+規(guī)范Promise

    摘要:手寫一款符合規(guī)范的長(zhǎng)篇預(yù)警有點(diǎn)長(zhǎng),可以選擇性觀看。初始狀態(tài)是,狀態(tài)可以有或者不能從轉(zhuǎn)換為或者從轉(zhuǎn)換成即只要由狀態(tài)轉(zhuǎn)換為其他狀態(tài)后,狀態(tài)就不可變更。 手寫一款符合Promise/A+規(guī)范的Promise 長(zhǎng)篇預(yù)警!有點(diǎn)長(zhǎng),可以選擇性觀看。如果對(duì)Promise源碼不是很清楚,還是推薦從頭看,相信你認(rèn)真從頭看到尾,并且去實(shí)際操作了,肯定會(huì)有收獲的。主要是代碼部分有點(diǎn)多,不過(guò)好多都是重復(fù)的,不...

    rubyshen 評(píng)論0 收藏0
  • 手寫一個(gè)符合A+規(guī)范Promise

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

    jsummer 評(píng)論0 收藏0
  • 手寫一個(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í)行用戶傳入 promise使用及原理分析: 通過(guò)new關(guān)鍵字創(chuàng)建promise實(shí)例, 接受一個(gè)executor參數(shù), executor方法返回兩個(gè)方法 res...

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

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

0條評(píng)論

閱讀需要支付1元查看
<