中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript如何實現序列化鏈式結構

發布時間:2022-05-23 10:51:17 來源:億速云 閱讀:164 作者:iii 欄目:大數據

這篇文章主要介紹了JavaScript如何實現序列化鏈式結構的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇JavaScript如何實現序列化鏈式結構文章都會有所收獲,下面我們一起來看看吧。

一、概述

在JavaScript中,鏈式模式代碼,太多太多,如下:

if_else:

if(...){     //TODO }else if(...){     //TODO }else{     //TODO }

switch:

switch(name){     case ...:{         //TODO         break;     }     case ...:{         //TODO         break;     }     default:{         //TODO         } }

疑問:諸如上述這些鏈式代碼,倘若,我們想將其扁平化鏈式處理呢?如下:

//fn1,f2,f3為處理函數 _if(fn1)._elseIf(fn2)._else(fn3);

下面我們就來一起嘗試實現下唄。

二、鏈式代碼扁平化

假如,現在我們有如下鏈式代碼:

if(name === 'Monkey'){     console.log('yes, I am Monkey'); }else if(name === 'Dorie'){     console.log('yes, I am Dorie'); }else{     console.log('sorry, over for ending!'); }

好了,現在我們一步一步將其”扁平化”。

其實看看上面的代碼,不難發現,if…else這種格式,其實就是數據結構中的單鏈表,那么,初步利用JavaScript實現單鏈表,如下:

var thens = []; thens.resolve = function(name){     for(var i = 0, len = this.length; i < len;i++){         if(this[i](name) !== 'next'){             break;         }     } } thens.push(f1, f2, f3);

其中f1,f2,f3為判斷函數,并且我們假設,如果諸如f1、f2、f3返回&rsquo;next&rsquo;時,就繼續往下查找,否則,停止往下查找。如下:

function f1(name){     if(name === 'Monkey'){         console.log('yes, I am Monkey');     }else{         return 'next';     } } function f2(name){     if(name === 'Dorie'){         console.log('yes, I am Dorie');     }else{         return 'next';     } } function f3(){     console.log('sorry, over for ending!'); }

好了,這就是鏈表的模式。

但是,我們的最終目的是想實現如下這樣的呢?

//fn1,f2,f3為處理函數 _if(fn1)._elseIf(fn2)._else(fn3);

你可能會說,將上述代碼改成如下這樣,不就好了嗎?!!

thens.push(f1).push(f2).push(f3).resolve();

But,JavaScript的push方法返回的是數組的新長度,而不是數組對象哦。

So,那我們只能新寫一個add方法,效果和push一樣,但是返回數組對象。如下:

thens.add = function(f){     if(typeof f === 'function'){         this.push(f);         return this;             }         }

測試代碼如下:

var thens = []; thens.add = function(f){     if(typeof f === 'function'){         this.push(f);         return this;             }         } thens.resolve = function(name){     for(var i = 0, len = this.length; i < len;i++){         if(this[i](name) !== 'next'){             break;         }     }     } thens.add(f1).add(f2).add(f3).resolve();

但是,這樣有個缺點,我們是將add、resolve方法綁定在全局變量thens中的,總不能每次創建一個數組時,都復制粘貼一遍方法吧,所以重構代碼如下:

function Slink(){     this.thens = [];     this.thens.add = function(f){         if(typeof f === 'function'){             this.push(f);             return this;                 }             }     this.thens.resolve = function(name){         for(var i = 0, len = this.length; i < len;i++){             if(this[i](name) !== 'next'){                 break;             }         }         } }

顯然,add,resolve這種公共方法,在每次實例化時,都創建一遍是不科學的,so,利用prototype在原有的基礎上繼續變形,如下:

function Slink(){     this.thens = []; } Slink.prototype = {     add: function(f){             if(typeof f === 'function'){                 this.thens.push(f);                 return this;                     }             },     resolve: function(name){             for(var i = 0, len = this.thens.length; i < len; i++){                 if(this.thens[i](name) !== 'next'){                     break;                 }             }         } }

測試代碼如下:

var thens = new Slink(); thens.add(f1).add(f2).add(f3); thens.resolve();

不錯,但是這樣,我們每次都得手動new一個Slink,有點麻煩,所以,我們將new Slink這個過程,封裝到函數中,如同jQuery一樣,如下:

function $go(f){     return new Slink(f); } function Slink(f){     this.thens = [];     this.thens.push(f); } Slink.prototype = {     add: function(f){             if(typeof f === 'function'){                 this.thens.push(f);                 return this;                     }             },     resolve: function(name){             for(var i = 0, len = this.thens.length; i < len; i++){                 if(this.thens[i](name) !== 'next'){                     break;                 }             }         } }

測試代碼如下:

$go(f1).add(f2).add(f3).resolve();

好了,大功告成,接下來就是語法糖滴問題咯,整理代碼如下:

function _if(f){     return new Slink(f); } function Slink(f){     this.thens = [];     this.thens.push(f); } Slink.prototype = {     _elseIf: function(f){             if(typeof f === 'function'){                 this.thens.push(f);                 return this;                     }             },     _else: function(f){             return this._elseIf(f);     },     resolve: function(name){             for(var i = 0, len = this.thens.length; i < len; i++){                 if(this.thens[i](name) !== 'next'){                     break;                 }             }             return this;                 } }

測試代碼如下:

_if(f1)._elseIf(f2)._else(f3).resolve();

當然,除開利用數組這種方式,還可以利用閉包,實現鏈式扁平化效果,如下:

var func = Function.prototype; func._else = func._elseIf = function(fn){     var _this = this;     return function(){         var res = _this.apply(this,arguments);         if(res==="next"){  //值為Boolean             return fn.apply(this,arguments);         }         return res;     } }

測試代碼如下:

function f1(name){     if(name === 'Monkey'){         console.log('yes, I am Monkey');     }else{         return 'next';     } } function f2(name){     if(name === 'Dorie'){         console.log('yes, I am Dorie');     }else{         return 'next';     } } function f3(){     console.log('sorry, over for ending!'); } f1._elseIf(f2)._else(f3)('Dorie');

三、異步代碼鏈式扁平化

在上面我們討論的都是同步過程,倘若,鏈式調用函數中有異步情況呢?

什么意思?如下:

function f1(name){     setTimeout(function(){         if(name === 'Monkey'){             console.log('yes, I am Monkey');         }else{             return 'next';         }     }, 2000); } function f2(name){     if(name === 'Dorie'){         console.log('yes, I am Dorie');     }else{         return 'next';     } } function f3(){     console.log('sorry, over for ending!'); }

我們將f1利用setTimeout變成了異步,按照上述代碼的邏輯,應該是等f1完全執行完畢(包括setTimeout執行)后,判斷是否執行f2,但真的如此嗎?

測試代碼如下:

_if(f1)._elseIf(f2)._else(f3).resolve();

執行代碼的結果就是,什么也不輸出。

Why?

因為JavaScript是單線程嘛。

那該怎么解決呢?

由于有異步代碼,且必須在異步代碼后處理后續的鏈,那么我們就等待異步代碼執行完畢后,才執行后續的鏈嘛,如下:

function f1(name){     setTimeout(function(){         if(name === 'Monkey'){             console.log('yes, I am Monkey');         }else{             //處理后續鏈             this.resolve(name, 1);//1代表下一個需處理函數在數組中的位置         }     }.bind(this), 2000); }

好了,由于在函數中,我們使用了this,其代表Slink對象,且改變了resolve方法,固,需細微調整Slink構造函數和原型鏈,如下:

function Slink(f){     this.thens = [];     this.thens.push(f.bind(this)); } Slink.prototype = {     _elseIf: function(f){             if(typeof f === 'function'){                 this.thens.push(f.bind(this));                 return this;                    }            },     _else: function(f){             return this._elseIf(f.bind(this));     },     resolve: function(name, flag){             for(var i = flag, len = this.thens.length; i < len; i++){                 if(this.thens[i](name) !== 'next'){                     break;                 }             }             return this;                } }

測試代碼如下:

function f1(name){     setTimeout(function(){         if(name === 'Monkey'){             console.log('yes, I am Monkey');         }else{             //處理后續鏈             this.resolve(name, 1);//1代表下一個需處理函數在數組中的位置         }     }.bind(this), 2000); } function f2(name){     if(name === 'Dorie'){         console.log('yes, I am Dorie');     }else{         return 'next';     } } function f3(){     console.log('sorry, over for ending!'); } _if(f1)._elseIf(f2)._else(f3).resolve('',0);

關于“JavaScript如何實現序列化鏈式結構”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“JavaScript如何實現序列化鏈式結構”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

安岳县| 台北市| 邵东县| 文昌市| 九寨沟县| 璧山县| 科技| 申扎县| 宜宾市| 阿勒泰市| 台东市| 固镇县| 台南县| 扬中市| 昌图县| 曲阜市| 富平县| 耒阳市| 旬阳县| 广西| 永安市| 阳西县| 珲春市| 大连市| 锡林郭勒盟| 曲阳县| 河东区| 靖边县| 谢通门县| 开远市| 都江堰市| 寿光市| 通许县| 尚志市| 威远县| 武平县| 亚东县| 瓦房店市| 册亨县| 清新县| 台中市|