<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

        如何從零開始利用js手寫一個(gè)Promise庫詳解

        來源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 22:16:28
        文檔

        如何從零開始利用js手寫一個(gè)Promise庫詳解

        如何從零開始利用js手寫一個(gè)Promise庫詳解:前言 ECMAScript 是 JavaScript 語言的國際標(biāo)準(zhǔn),JavaScript 是 ECMAScript 的實(shí)現(xiàn)。ES6 的目標(biāo),是使得 JavaScript 語言可以用來編寫大型的復(fù)雜的應(yīng)用程序,成為企業(yè)級開發(fā)語言。 概念 ES6 原生提供了 Promise 對象。 所謂 Promise,就
        推薦度:
        導(dǎo)讀如何從零開始利用js手寫一個(gè)Promise庫詳解:前言 ECMAScript 是 JavaScript 語言的國際標(biāo)準(zhǔn),JavaScript 是 ECMAScript 的實(shí)現(xiàn)。ES6 的目標(biāo),是使得 JavaScript 語言可以用來編寫大型的復(fù)雜的應(yīng)用程序,成為企業(yè)級開發(fā)語言。 概念 ES6 原生提供了 Promise 對象。 所謂 Promise,就

        前言

        ECMAScript 是 JavaScript 語言的國際標(biāo)準(zhǔn),JavaScript 是 ECMAScript 的實(shí)現(xiàn)。ES6 的目標(biāo),是使得 JavaScript 語言可以用來編寫大型的復(fù)雜的應(yīng)用程序,成為企業(yè)級開發(fā)語言。

        概念

        ES6 原生提供了 Promise 對象。

        所謂 Promise,就是一個(gè)對象,用來傳遞異步操作的消息。它代表了某個(gè)未來才會知道結(jié)果的事件(通常是一個(gè)異步操作),并且這個(gè)事件提供統(tǒng)一的 API,可供進(jìn)一步處理。

        三道思考題

        剛開始寫前端的時(shí)候,處理異步請求經(jīng)常用callback,簡單又順手。后來寫著寫著就拋棄了callback,開始用promise來處理異步問題。promise寫起來確實(shí)更加優(yōu)美,但由于缺乏對它內(nèi)部結(jié)構(gòu)的深刻認(rèn)識,每次在遇到一些復(fù)雜的情況時(shí),promise用起來總是不那么得心應(yīng)手,debug也得搞半天。

        所以,這篇文章我會帶大家從零開始,手寫一個(gè)基本能用的promise。跟著我寫下來以后,你會對promise是什么以及它的內(nèi)部結(jié)構(gòu)有一個(gè)清楚的認(rèn)知,未來在復(fù)雜場景下使用promise也能如魚得水。

        而且,為了檢驗(yàn)大家是否真的完全掌握了promise,我會在文章結(jié)尾出幾道跟promise相關(guān)的練習(xí)題。說是練習(xí)題,其實(shí)都是大家項(xiàng)目中會遇到的真實(shí)場景的抽象,熟練掌握可以幫助大家在前端方面更上一層樓。

        提前將三道練習(xí)題給出來,大家可以先不看下文的內(nèi)容,在腦海里大概構(gòu)思下你會怎么解決:

      1. promise array的鏈?zhǔn)秸{(diào)用?
      2. promise怎么做并發(fā)控制?
      3. promise怎么做異步緩存?
      4. 以上三道思考題其實(shí)跟你用不用promise并沒有多大關(guān)系,但是如果你不深刻理解promise想要解決這三個(gè)問題還真不是那么輕松的。

        什么是Promise

        回到正文,什么是Promise?說白了,promise就是一個(gè)容器,里面保存著某個(gè)未來才會結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果。

        首先,ES6規(guī)定Promise對象是一個(gè)構(gòu)造函數(shù),用來生成Promise實(shí)例。然后,這個(gè)構(gòu)造函數(shù)接受一個(gè)函數(shù)(executor)作為參數(shù),該函數(shù)的兩個(gè)參數(shù)分別是resolve和reject。最后,Promise實(shí)例生成以后,可以用then方法分別指定resolved狀態(tài)和rejected狀態(tài)的回調(diào)函數(shù)(onFulfilled和onRejected)。

        具體的使用方法,用代碼表現(xiàn)是這樣:

        const promise = new Promise(function(resolve, reject) {
         // ... some code
        
         if (/* 異步操作成功 */){
         resolve(value);
         } else {
         reject(error);
         }
        });
        
        promise.then(function(value) {
         // success
        }, function(error) {
         // failure
        });

        理解了這個(gè)后,我們就可以大膽的開始構(gòu)造我們自己的promise了,我們給它取個(gè)名字:CutePromise

        實(shí)現(xiàn)一個(gè)Promise:CutePromise

        我們直接用ES6的class來創(chuàng)建我們的CutePromise,對ES6語法還不熟悉的,可以先讀一下我的另外兩篇介紹ES6核心語法的文章后再回來。30分鐘掌握ES6/ES2015核心內(nèi)容(上) 、30分鐘掌握ES6/ES2015核心內(nèi)容(下)

        class CutePromise {
         // executor是我們實(shí)例化CutePromise時(shí)傳入的參數(shù)函數(shù),它接受兩個(gè)參數(shù),分別是resolve和reject。
         // resolve和reject我們將會定義在constructor當(dāng)中,供executor在執(zhí)行的時(shí)候調(diào)用
         constructor(executor) {
         const resolve = () => {}
         const reject = () => {}
         executor(resolve, reject)
         }
        
         // 為實(shí)例提供一個(gè)then的方法,接收兩個(gè)參數(shù)函數(shù),
         // 第一個(gè)參數(shù)函數(shù)必傳,它會在promise已成功(fulfilled)以后被調(diào)用
         // 第二個(gè)參數(shù)非必傳,它會在promise已失敗(rejected)以后被調(diào)用
         then(onFulfilled, onRejected) {}
        }

        創(chuàng)建了我們的CutePromise后,我們再來搞清楚一個(gè)關(guān)鍵點(diǎn):Promise 對象的狀態(tài)。

        Promise 對象通過自身的狀態(tài),來控制異步操作。一個(gè)Promise 實(shí)例具有三種狀態(tài):

      5. 異步操作未完成(pending)
      6. 異步操作成功(fulfilled)
      7. 異步操作失敗(rejected)
      8. 上面三種狀態(tài)里面,fulfilled和rejected合在一起稱為resolved(已定型)。狀態(tài)的切換只有兩條路徑:第一種是從pending=>fulfilled,另一種是從pending=>rejected,狀態(tài)一旦切換就不能再改變。

        現(xiàn)在我們來為CutePromise添加狀態(tài),大概流程就是:

        首先,實(shí)例化初始過程中,我們先將狀態(tài)設(shè)為PENDING,然后當(dāng)executor執(zhí)行resolve的時(shí)候,將狀態(tài)更改為FULFILLED,當(dāng)executor執(zhí)行reject的時(shí)候?qū)顟B(tài)更改為REJECTED。同時(shí)更新實(shí)例的value。

        constructor(executor) {
         ...
         this.state = 'PENDING';
         ...
         const resolve = (result) => {
         this.state = 'FULFILLED';
         this.value = result;
         }
         const reject = (error) => {
         this.state = 'REJECTED';
         this.value = error;
         }
         ...
        }

        再來看下我們的then函數(shù)。then函數(shù)的兩個(gè)參數(shù),onFulfilled表示當(dāng)promise異步操作成功時(shí)調(diào)用的函數(shù),onRejected表示當(dāng)promise異步操作失敗時(shí)調(diào)用的函數(shù)。假如我們調(diào)用then的時(shí)候,promise已經(jīng)執(zhí)行完成了(當(dāng)任務(wù)是個(gè)同步任務(wù)時(shí)),我們可以直接根據(jù)實(shí)例的狀態(tài)來執(zhí)行相應(yīng)的函數(shù)。假如promise的狀態(tài)還是PENDING, 那我們就將onFulfilled和onRejected直接存儲到chained這個(gè)變量當(dāng)中,等promise執(zhí)行完再調(diào)用。

        constructor(executor) {
         ...
         this.state = 'PENDING';
         
         // chained用來儲存promise執(zhí)行完成以后,需要被依次調(diào)用的一系列函數(shù)
         this.chained = [];
         const resolve = (result) => {
         this.state = 'FULFILLED';
         this.value = result;
         
         // promise已經(jīng)執(zhí)行成功了,可以依次調(diào)用.then()函數(shù)里的onFulfilled函數(shù)了
         for (const { onFulfilled } of this.chained) {
         onFulfilled(res);
         }
         }
        
         ...
        }
        then(onFulfilled, onRejected) {
         if (this.state === 'FULFILLED') {
         onFulfilled(this.value);
         } else if (this.state === 'REJECTED') {
         onRejected(this.value);
         } else {
         this.$chained.push({ onFulfilled, onRejected });
         }
        }

        這樣我們就完成了一個(gè)CutePromise的創(chuàng)建,下面是完整代碼,大家可以到控制臺測試一下:

        class CutePromise {
         constructor(executor) {
         if (typeof executor !== 'function') {
         throw new Error('Executor must be a function');
         }
        
         this.state = 'PENDING';
         this.chained = [];
         const resolve = res => {
         if (this.state !== 'PENDING') {
         return;
         }
        
         this.state = 'FULFILLED';
         this.internalValue = res;
         for (const { onFulfilled } of this.chained) {
         onFulfilled(res);
         }
         };
         const reject = err => {
         if (this.state !== 'PENDING') {
         return;
         }
         this.state = 'REJECTED';
         this.internalValue = err;
         for (const { onRejected } of this.chained) {
         onRejected(err);
         }
         };
        
         try {
         executor(resolve, reject);
         } catch (err) {
         reject(err);
         }
         }
         
         then(onFulfilled, onRejected) {
         if (this.state === 'FULFILLED') {
         onFulfilled(this.internalValue);
         } else if (this.$state === 'REJECTED') {
         onRejected(this.internalValue);
         } else {
         this.chained.push({ onFulfilled, onRejected });
         }
         }
        }

        提供一下測試代碼:

        let p = new CutePromise(resolve => {
         setTimeout(() => resolve('Hello'), 100);
        });
        p.then(res => console.log(res));
        p = new CutePromise((resolve, reject) => {
         setTimeout(() => reject(new Error('woops')), 100);
        });
        p.then(() => {}, err => console.log('Async error:', err.stack));
        p = new CutePromise(() => { throw new Error('woops'); });
        p.then(() => {}, err => console.log('Sync error:', err.stack));

        總結(jié)

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        如何從零開始利用js手寫一個(gè)Promise庫詳解

        如何從零開始利用js手寫一個(gè)Promise庫詳解:前言 ECMAScript 是 JavaScript 語言的國際標(biāo)準(zhǔn),JavaScript 是 ECMAScript 的實(shí)現(xiàn)。ES6 的目標(biāo),是使得 JavaScript 語言可以用來編寫大型的復(fù)雜的應(yīng)用程序,成為企業(yè)級開發(fā)語言。 概念 ES6 原生提供了 Promise 對象。 所謂 Promise,就
        推薦度:
        • 熱門焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲国产精品不卡毛片a在线| 免费人成毛片动漫在线播放| 亚洲最大的视频网站| 亚洲电影免费观看| 亚洲欧洲无卡二区视頻| 精品免费AV一区二区三区| 亚洲一区二区三区在线网站| 日本激情猛烈在线看免费观看| 免费无码av片在线观看 | 亚洲黄色片在线观看| 亚洲国产系列一区二区三区| 一级特级女人18毛片免费视频| 免费成人在线视频观看| 亚洲av永久无码精品秋霞电影影院 | a毛片在线免费观看| 成全影视免费观看大全二| 又黄又爽一线毛片免费观看| 中文字幕亚洲一区| 亚洲色大成WWW亚洲女子| 日韩在线不卡免费视频一区| 国产成人免费片在线视频观看| 亚洲Av熟妇高潮30p| 成人网站免费大全日韩国产| 精品国产麻豆免费网站| 亚洲AV人无码综合在线观看| 最近高清中文字幕免费| 亚洲尤码不卡AV麻豆| 国产精品亚洲一区二区三区| 亚洲日韩在线中文字幕第一页| 亚洲成a人片在线看| 国产一级淫片视频免费看 | 亚洲精品宾馆在线精品酒店| 久久一本岛在免费线观看2020| 亚洲日韩aⅴ在线视频| 一区二区三区四区免费视频| 亚洲 日韩 色 图网站| 亚洲国产一成久久精品国产成人综合| 亚洲人成色777777精品| 亚洲日本一区二区一本一道| 老汉精品免费AV在线播放| 亚洲熟妇无码一区二区三区|