欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Promise 鏈式調(diào)用原理精簡示例

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

前言

在面試的過程中,總有一些面試官會問你,手寫一個簡易版的Promise得行不,得行的話就寫一個出來看看,啪一哈,就把紙和筆給了你。 我們思索半天就寫出來了個下面這個。 哦豁,高薪張開了它的翅膀,遠離了我們。

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

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

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

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

代碼

function CustomPromise (fn) {
    // 回調(diào)收集
    this.callbackList = []
    // 傳遞給Promise處理函數(shù)的resolve
    const resolve = (value) => {
        // 注意promise的then函數(shù)需要異步執(zhí)行
        setTimeout(() => {
            // 這里直接往實例上掛個data
            this.data = value;
            // 把callbackList數(shù)組里的函數(shù)依次執(zhí)行一遍
            this.callbackList.forEach(cb => cb(value))
        });
    }
    /*
        執(zhí)行用戶傳入的函數(shù) 
        并且把resolve方法交給用戶執(zhí)行
    */ 
    fn(resolve)
}
/*
    重點
*/
// 往構(gòu)造函數(shù)的原型上掛載.then方法
CustomPromise.prototype.then = function (onReaolved) {
    // return 一個promise 實例
    return new CustomPromise((resolve) => {
        // 往回調(diào)數(shù)組中插入回調(diào)
        this.callbackList.push(()=>{
            const response = onReaolved(this.data)
            // 判斷是否是一個 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);
        // 返回一個 CustomPromise 
        return new CustomPromise((resolve) => {
            setTimeout(() => {
                // resolve2
                resolve(2);
            }, 300);
        });
    }).then(res => {// then2
        console.log(res);
    });

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

解析

第一步

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

大概步驟如下:

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

寫出來后的樣子長這樣:

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

第二步

注意:第二步是本篇文章的重點,也是這個核心功能的一個重點。

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

完整代碼長這樣:

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

寫出來過后,在結(jié)合上面的那個例子使用,不能說和原生Promise一模一樣,但使用起來的鏈式效果卻是一毛一樣。

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

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

說明:

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

如果用戶傳入給thenonResolved方法返回的是個userPromise,那么這個userPromise里用戶會自己去在合適的時機 resolvePromise2,那么進而這里的response.then(resolve) 中的resolve就會被執(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這一整塊其實返回的是promise2,那么then2 其實本質(zhì)上是promise2.then(()=>{}), 也就是說then2注冊的回調(diào)函數(shù),其實進入了promise2callbackList回調(diào)數(shù)組里。 又因為我們剛剛知道,resolve2調(diào)用了之后,userPromise 會被resolve,進而觸發(fā)promise2resolve,進而 promise2里的callbackList數(shù)組被依次觸發(fā)。 這樣就實現(xiàn)了用戶自己寫的resolve2執(zhí)行完畢后,then2里的邏輯才會繼續(xù)執(zhí)行,也就是異步鏈式調(diào)用。

說句題外話,這個有點繞,當時還是看了好一會才看懂。

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

總結(jié)

本篇文章只是根據(jù)其原理實現(xiàn)的一個簡易鏈式調(diào)用的過程,真正的Promise并沒有這么簡單,和上文中的比起來復雜很多,而且涉及到很多的異常、容錯、邊界等情況的處理。

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

以上就是Promise 鏈式調(diào)用原理精簡示例的詳細內(nèi)容,更多關(guān)于Promise 鏈式調(diào)用的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論