亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Promise 鏈?zhǔn)秸{(diào)用原理精簡(jiǎn)示例

 更新時(shí)間:2022年12月14日 14:59:24   作者:桃小瑞  
這篇文章主要為大家介紹了Promise 鏈?zhǔn)秸{(diào)用原理精簡(jiǎn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

在面試的過(guò)程中,總有一些面試官會(huì)問(wèn)你,手寫(xiě)一個(gè)簡(jiǎn)易版的Promise得行不,得行的話就寫(xiě)一個(gè)出來(lái)看看,啪一哈,就把紙和筆給了你。 我們思索半天就寫(xiě)出來(lái)了個(gè)下面這個(gè)。 哦豁,高薪張開(kāi)了它的翅膀,遠(yuǎn)離了我們。

class Promise {
    constructor (resolve, reject) {}
    resolve () {}
    reject (){}
    then () {}
    catch () {}
    once () {}
    all () {}
    ...
}

本篇文章將不講述手寫(xiě)出來(lái)一個(gè)簡(jiǎn)易的Promise,感興趣的朋友可以去看我這篇文章 -> Promise詳解-手寫(xiě)Promise,實(shí)現(xiàn)一款自己的簡(jiǎn)易Promise

本篇文章記錄的是如何實(shí)現(xiàn)Promise的核心功能之一的.then 鏈?zhǔn)秸{(diào)用,采用構(gòu)造函數(shù)的寫(xiě)法,本篇文章的代碼不考慮任何容錯(cuò)和異常處理,只單獨(dú)說(shuō)明其鏈?zhǔn)秸{(diào)用原理,方便理解。

先擺上完整代碼,去掉注釋和一些換行共20行有余。

代碼

function CustomPromise (fn) {
    // 回調(diào)收集
    this.callbackList = []
    // 傳遞給Promise處理函數(shù)的resolve
    const resolve = (value) => {
        // 注意promise的then函數(shù)需要異步執(zhí)行
        setTimeout(() => {
            // 這里直接往實(shí)例上掛個(gè)data
            this.data = value;
            // 把callbackList數(shù)組里的函數(shù)依次執(zhí)行一遍
            this.callbackList.forEach(cb => cb(value))
        });
    }
    /*
        執(zhí)行用戶傳入的函數(shù) 
        并且把resolve方法交給用戶執(zhí)行
    */ 
    fn(resolve)
}
/*
    重點(diǎn)
*/
// 往構(gòu)造函數(shù)的原型上掛載.then方法
CustomPromise.prototype.then = function (onReaolved) {
    // return 一個(gè)promise 實(shí)例
    return new CustomPromise((resolve) => {
        // 往回調(diào)數(shù)組中插入回調(diào)
        this.callbackList.push(()=>{
            const response = onReaolved(this.data)
            // 判斷是否是一個(gè) CustomPromise
            if(response instanceof CustomPromise){
                // resolve 的權(quán)力被交給了user promise
                response.then(resolve)
            }else{
                // 如果是普通值,直接resolve
                // 依次執(zhí)行callbackList里的函數(shù) 并且把值傳遞給callbackList
                resolve(response)
            }
        })
    })
}

經(jīng)典案例

    new CustomPromise((resolve) => {
        setTimeout(() => {
            // resolve1
            resolve(1);
        }, 300);
    }).then((res) => {// then1
        console.log(res);
        // 返回一個(gè) CustomPromise 
        return new CustomPromise((resolve) => {
            setTimeout(() => {
                // resolve2
                resolve(2);
            }, 300);
        });
    }).then(res => {// then2
        console.log(res);
    });

完整的代碼和例子已奉上,現(xiàn)在來(lái)進(jìn)行解釋。 固然結(jié)果很重要,但過(guò)程也很重要。我們要做到 知其然知其所以然。

解析

第一步

首先,我們我們先創(chuàng)建這樣一個(gè)Promise, 這里需要使用匿名函數(shù),不能使用箭頭函數(shù),或者你可以根據(jù)這個(gè)方法已class 類的方法進(jìn)行實(shí)現(xiàn)。

大概步驟如下:

  • 聲明構(gòu)造函數(shù)/類
  • 在內(nèi)部聲明一個(gè)數(shù)組名為callbackList用來(lái)裝回調(diào),并放到this里面
  • 聲明一個(gè)名resolve的方法,用來(lái)傳遞給Promise進(jìn)行處理,注意:resolve 內(nèi)部需要為異步,這里可以采用 setTimeout 實(shí)現(xiàn)
  • 循環(huán)callbackList并執(zhí)行里面的方法

寫(xiě)出來(lái)后的樣子長(zhǎng)這樣:

function CustomPromise (fn) {
    // 回調(diào)收集
    this.callbackList = []
    // 傳遞給Promise處理函數(shù)的resolve
    const resolve = (value) => {
        // 注意promise的then函數(shù)需要異步執(zhí)行
        setTimeout(() => {
            // 這里直接往實(shí)例上掛個(gè)data
            this.data = value;
            // 把callbackList數(shù)組里的函數(shù)依次執(zhí)行一遍
            this.callbackList.forEach(cb => cb(value))
        });
    }
    /*
        - fn 為用戶傳進(jìn)來(lái)的函數(shù)
        - 執(zhí)行用戶傳入的函數(shù) 
        - 并且把resolve方法交給用戶執(zhí)行
    */ 
    fn(resolve)
}

第二步

注意:第二步是本篇文章的重點(diǎn),也是這個(gè)核心功能的一個(gè)重點(diǎn)。

我們需要往CustomPromise的原型上掛載一個(gè).then的方法。并返回的是一個(gè)Promise實(shí)例,這里依舊使用的是匿名函數(shù)。

完整代碼長(zhǎng)這樣:

// 往構(gòu)造函數(shù)的原型上掛載.then方法
CustomPromise.prototype.then = function (onReaolved) {
    // return 一個(gè)promise 實(shí)例
    return new CustomPromise((resolve) => {
        // 往回調(diào)數(shù)組中插入回調(diào)
        this.callbackList.push(()=>{
            const response = onReaolved(this.data)
            // 判斷是否是一個(gè) CustomPromise
            if(response instanceof CustomPromise){
                // resolve 的權(quán)力被交給了user promise
                response.then(resolve)
            }else{
                // 如果是普通值,直接resolve
                // 依次執(zhí)行callbackList里的函數(shù) 并且把值傳遞給callbackList
                resolve(response)
            }
        })
    })
}

寫(xiě)出來(lái)過(guò)后,在結(jié)合上面的那個(gè)例子使用,不能說(shuō)和原生Promise一模一樣,但使用起來(lái)的鏈?zhǔn)叫Ч麉s是一毛一樣。

分析說(shuō)明,此過(guò)程需結(jié)合上文中的案例一起閱讀

    const promise1 = new CustomPromise((resolve) => {
        setTimeout(() => resolve(1));
    })
    promise1.then((res) => {
        const userPromise = new CustomPromise((resolve) => {
            setTimeout(() => resolve(2), 300);
        });
        return userPromise
    });

說(shuō)明:

  • 我們把new Promise返回的實(shí)例叫做promise1
  • Promise.prototype.then的實(shí)現(xiàn)中,我們構(gòu)造了一個(gè)新的promise 返回,叫它promise2 在調(diào)用then方法的時(shí)候,用戶手動(dòng)構(gòu)造了一個(gè)promise并且返回,用來(lái)做異步的操作,叫它userPromise,那么在then的實(shí)現(xiàn)中,內(nèi)部的this其實(shí)就指向promise1promise2的傳入的fn函數(shù)執(zhí)行了一個(gè)this.cbs.push()的操作,其實(shí)是往promise1callbackList數(shù)組中push了一個(gè)函數(shù),等待后續(xù)執(zhí)行
CustomPromise.prototype.then = function (onReaolved) {
    // promise 2
    return new CustomPromise((resolve) => {
        // 往回調(diào)數(shù)組中插入回調(diào)
        this.callbackList.push(()=>{})
    })
}

如果用戶傳入給thenonResolved方法返回的是個(gè)userPromise,那么這個(gè)userPromise里用戶會(huì)自己去在合適的時(shí)機(jī) resolvePromise2,那么進(jìn)而這里的response.then(resolve) 中的resolve就會(huì)被執(zhí)行

if(response instanceof CustomPromise){
    response.then(resolve)
}

再結(jié)合上面的經(jīng)典案例看,我這里再放一遍

    new CustomPromise((resolve) => {
        setTimeout(() => {
            // resolve1
            resolve(1);
        }, 300);
    }).then((res) => {// then1
        console.log(res);
        // userPromise
        return new CustomPromise((resolve) => {
            setTimeout(() => {
                // resolve2
                resolve(2);
            }, 300);
        });
    }).then(res => {// then2
        console.log(res);
    });

then1這一整塊其實(shí)返回的是promise2,那么then2 其實(shí)本質(zhì)上是promise2.then(()=>{}), 也就是說(shuō)then2注冊(cè)的回調(diào)函數(shù),其實(shí)進(jìn)入了promise2callbackList回調(diào)數(shù)組里。 又因?yàn)槲覀儎倓傊溃?code>resolve2調(diào)用了之后,userPromise 會(huì)被resolve,進(jìn)而觸發(fā)promise2resolve,進(jìn)而 promise2里的callbackList數(shù)組被依次觸發(fā)。 這樣就實(shí)現(xiàn)了用戶自己寫(xiě)的resolve2執(zhí)行完畢后,then2里的邏輯才會(huì)繼續(xù)執(zhí)行,也就是異步鏈?zhǔn)秸{(diào)用。

說(shuō)句題外話,這個(gè)有點(diǎn)繞,當(dāng)時(shí)還是看了好一會(huì)才看懂。

好了,當(dāng)你看到這里的時(shí)候,這篇文章已經(jīng)接近尾聲了,是時(shí)候進(jìn)行總結(jié)了。

總結(jié)

本篇文章只是根據(jù)其原理實(shí)現(xiàn)的一個(gè)簡(jiǎn)易鏈?zhǔn)秸{(diào)用的過(guò)程,真正的Promise并沒(méi)有這么簡(jiǎn)單,和上文中的比起來(lái)復(fù)雜很多,而且涉及到很多的異常、容錯(cuò)、邊界等情況的處理。

最后推薦一下Promise A+規(guī)范 -> 點(diǎn)我查看規(guī)范,很值得去看,相信看完后會(huì)對(duì)Promise有一個(gè)更深的了解。

以上就是Promise 鏈?zhǔn)秸{(diào)用原理精簡(jiǎn)示例的詳細(xì)內(nèi)容,更多關(guān)于Promise 鏈?zhǔn)秸{(diào)用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論