mass Framework在後端的核心模組

來源:互聯網
上載者:User

mass Framework前後通吃,後端是基於node.js組建起來。後端與前端不一樣,是依賴於node.js內建模組提供的一些API,因此前端那些依賴於瀏覽器提供的DOM API的模組無法複用。現在掐指一算,基本上核心模組上只有lang, flow能用得上,more則多一點,如random, pinyin, base64, uuid...

node.js內建了模組載入機制,這與我在前端使用的API非常不一致,我就再把它封裝一層。核心模組與前端的核心模組在其他方法也盡量保持一致,當然像domReady在後端就不需要,去掉。如類型判定,由於是V8引擎,支援ECMA262v5,因此可以寫得精簡。最大的不同是,DEBUG用到mass.log,它的第二個參數是表示格式化高亮。

代碼是暫時丟在這裡,以後還要做各種擴充的!

(function(){    //後端部分 2011.12.4 by 司徒正美    function mass(){}    var    version = 0.1,    class2type = {        "[object global]" : "Global" ,        "null" : "Null" ,        "NaN"  : "NaN"  ,        "undefined" : "Undefined"    },    toString = class2type.toString;    /**     * 糅雜,為一個對象添加更多成員     * @param {Object} target 目標對象     * @param {Object} source 屬性包     * @return {Object} 目標對象     */    function mix(target, source){        var args = [].slice.call(arguments), key,        ride = typeof args[args.length - 1] == "boolean" ? args.pop() : true;        target = target || {};        for(var i = 1; source = args[i++];){            for (key in source) {                if (ride || !(key in target)) {                    target[key] = source[key];                }            }        }        return target;    }    var rformat = /([\d\D]+?)/ig;    var formats = {        bold     : [1, 22],        italic    : [3, 23],        underline : [4, 24],        inverse   : [7, 27],        strike    : [9, 29]    };    var colors = {};    ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'].forEach(function(word,i){        colors[word] = i    });    colors.gray = 99;    function format (arr, str) {        return '\x1b[' + arr[0] + 'm' + str + '\x1b[' + arr[1] + 'm';    };    mix(mass,{//為此版本的命名空間對象新增成員        rword : /[^, ]+/g,        v : version,        "@debug" : true,        root: process.cwd(),        /**         * 數組化         * @param {ArrayLike} nodes 要處理的類數組對象         * @param {Number} start 可選。要抽取的片斷的起始下標。如果是負數,從後面取起         * @param {Number} end 可選。規定從何處結束選取         * @return {Array}         */        slice: function (nodes, start, end) {            for(var i = 0,n = nodes.length, result = []; i < n; i++){                result[i] = nodes[i];            }            if (arguments.length > 1) {                return result.slice(start , (end || result.length));            } else {                return result;            }        },        /**         * 用於取得資料的類型或判定資料的類型         * @param {Any} obj 要檢測的東西         * @param {String} str 要比較的類型         * @return {String|Boolean}         */        type : function (obj, str){            var result = class2type[ (obj == null || obj !== obj )? obj : toString.call(obj) ] || "#";            if( result.charAt(0) === "#"){                if(Buffer.isBuffer(obj)){                    result = 'Buffer'; //返回構造器名字                }else{                    result = toString.call(obj).slice(8,-1);                }            }            if(str){                return str === result;            }            return result;        },        /**         * 用於調試         * @param {String} s 要列印的內容         * @param {Boolean} color 進行各種顏色的高亮,使用<code style="format:blod;color:red;background:green">         * format的值可以為formats中五個之一或它們的組合(以空格隔開),背景色與字型色只能為colors之一         */        log:function (s, color){            if(color){                s = s.replace(rformat,function(a,style,ret){                    style.toLowerCase().split(";").forEach(function(arr){                        arr = arr.split(":");                        var type = arr[0].trim(),val = arr[1].trim();                        switch(type){                            case "format":                                val.replace(/\w+/g,function(word){                                    if(formats[word]){                                        ret = format(formats[word],ret)                                    }                                });                                break;                            case "background":                            case "color":                                var array = type == "color" ? [30,39] : [40,49]                                if( colors[val]){                                    array[0] += colors[val]                                    ret = format(array,ret)                                }                        }                    });                    return ret;                });            }            console.log(s);        },        /**         * 產生索引值統一的對象,用於高速化判定         * @param {Array|String} array 如果是字串,請用","或空格分開         * @param {Number} val 可選,預設為1         * @return {Object}         */        oneObject : function(array, val){            if(typeof array == "string"){                array = array.match(mass.rword) || [];            }            var result = {},value = val !== void 0 ? val :1;            for(var i=0,n=array.length;i < n;i++){                result[array[i]] = value;            }            return result;        },        mix:mix    });    mass.noop = mass.error = function(){};    "Boolean,Number,String,Function,Array,Date,RegExp,Arguments".replace(mass.rword,function(name){        class2type[ "[object " + name + "]" ] = name;    });    var    rmodule = /([^(\s]+)\(?([^)]*)\)?/,    names = [],//需要處理的模組名列表    rets = {},//用於收集模組的傳回值    cbi = 1e4 ;//用於產生回呼函數的名字    var map = mass["@modules"] = {};    //執行並移除所有依賴都具備的模組或回調    function resolveCallbacks(){        loop:        for (var i = names.length,repeat, name; name = names[--i]; ) {            var  obj = map[name], deps = obj.deps;            for(var key in deps){                if(deps.hasOwnProperty(key) && map[key].state != 2 ){                    continue loop;                }            }            //如果deps是Null 物件或者其依賴的模組的狀態都是2            if( obj.state != 2){                names.splice(i,1);//必須先移除再執行                var fn = obj.callback;                rets[fn._name] = fn.apply(null,incarnate(obj.args));//只收集模組的傳回值                obj.state = 2;                repeat = true;            }        }    repeat &&  resolveCallbacks();    }    function incarnate(args){//傳入一組模組名,返回對應模組的傳回值        for(var i = 0,ret = [], name; name = args[i++];){            ret.push(rets[name]);        }        return ret;    }    function deferred(){//一個簡單的非同步列隊        var list = [],self = function(fn){            fn && fn.call && list.push(fn);            return self;        }        self.method = "pop";        self.fire = function(fn){            while(fn = list[self.method]()){                fn();            }            return list.length ? self : self.complete();        }        self.complete = mass.noop;        return self;    }    var nativeModules = mass.oneObject("assert,child_process,cluster,crypto,dgram,dns,"+        "events,fs,http,https,net,os,path,querystring,readline,repl,tls,tty,url,util,vm,zlib")    function useNativeRequire(name,url){        var nick = name.slice(1);        if(nativeModules[nick]){            map[name].state = 2;            rets[name] = require(nick);            resolveCallbacks();        }else{            url = url  || mass.root+"/" + nick + ".js";            try{                require(url);                resolveCallbacks()            }catch(e){                mass.stack(Function('mass.log("\033[31m'+e+'\033[39m")'));                mass.stack.fire();//列印錯誤堆棧            }        }    }    mass.mix(mass,{        stack : deferred(),        define:function(name,deps,callback){//模組名,依賴列表,模組本身            if(typeof deps == "function"){//處理只有兩個參數的情況                callback = deps;                deps = "";            }            callback._name = "@"+name; //模組名            this.require(deps,callback);        },        require:function(deps,callback,errback){//依賴列表,正向回調,負向回調            var _deps = {}, args = [], dn = 0, cn = 0;            (deps +"").replace(mass.rword,function(url,name,match){                dn++;                match = url.match(rmodule);                name = "@"+ match[1];//取得模組名                if(!map[name]){ //防止重複產生節點與請求                    map[name] = { };//state: undefined, 未載入; 1 已載入; 2 : 已執行                    useNativeRequire(name,match[2]);//載入模組                }else if(map[name].state === 2){                    cn++;                }                if(!_deps[name] ){                    args.push(name);                    _deps[name] = "司徒正美";//去重                }            });            var cbname = callback._name;            if(dn === cn ){//在依賴都已執行過或沒有依賴的情況下                if(cbname && !(cbname in rets)){                    map[cbname].state = 2 //如果是使用合并方式,模組會跑進此分支(只會執行一次)                    return rets[cbname] =  callback.apply(null,incarnate(args));                   }else if(!cbname){//普通的回調可執行無數次                    return callback.apply(null,incarnate(args))                }            }            cbname = cbname || "@cb"+ (cbi++).toString(32);            if(errback){                mass.stack(errback);//壓入錯誤堆棧            }            map[cbname] = {//建立或更新模組的狀態                callback:callback,                deps:_deps,                args: args,                state: 1            };//在正常情況下模組只能通過resolveCallbacks執行            names.unshift(cbname);            resolveCallbacks();        }            });    exports.mass = global.mass = mass;})();

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.