国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

requirejs源碼解析之運(yùn)行流程

KavenFan / 1030人閱讀

摘要:說明內(nèi)容主要包括三部分按源碼的結(jié)構(gòu)順序?qū)λ械淖兞考胺椒ǖ恼f明運(yùn)行流程流程相關(guān)圖片一源碼的結(jié)構(gòu)為了方便比對源碼,按源碼的結(jié)構(gòu)順序展示。

說明:
內(nèi)容主要包括三部分:
1.按源碼的結(jié)構(gòu)順序 對 所有的變量及方法的說明
2.requirejs運(yùn)行流程
3、流程相關(guān)圖片

一、源碼的結(jié)構(gòu)

為了方便比對源碼,按源碼的結(jié)構(gòu)順序展示。

var requirejs, require, define;
(function (global, setTimeout) {
    var req, s, head, baseElement, dataMain, src,
        interactiveScript, currentlyAddingScript, mainScript, subPath,
        version = "2.3.5",
        commentRegExp = //*[sS]*?*/|([^:""=]|^)//.*$/mg,            //去除注釋
        cjsRequireRegExp = /[^.]s*requires*(s*[""]([^""s]+)[""]s*)/g,//提取require函數(shù)的arguments
        jsSuffixRegExp = /.js$/,
        currDirRegExp = /^.//,
        op = Object.prototype,
        ostring = op.toString,
        hasOwn = op.hasOwnProperty,
        isBrowser = !!(typeof window !== "undefined" && typeof navigator !== "undefined" && window.document),
        isWebWorker = !isBrowser && typeof importScripts !== "undefined",
        readyRegExp = isBrowser && navigator.platform === "PLAYSTATION 3" ?
                      /^complete$/ : /^(complete|loaded)$/,
        defContextName = "_",
        isOpera = typeof opera !== "undefined" && opera.toString() === "[object Opera]",
        contexts = {},
        cfg = {},
        globalDefQueue = [],
        useInteractive = false;
    //返回singlePrefix或空
    function commentReplace(match, singlePrefix) {}
    //判斷函數(shù)
    function isFunction(it) {}
    //判斷數(shù)組
    function isArray(it) {}
    //執(zhí)行函數(shù)func(ary[i], i, ary);返回真值,跳出循環(huán)
    function each(ary, func) {}
    //與each序列反
    function eachReverse(ary, func) {}
    //判斷obj是否有prop
    function hasProp(obj, prop) {}
    //返回obj上的prop
    function getOwn(obj, prop) {}
    //循環(huán)調(diào)用func(obj[prop], prop);返回真值,跳出循環(huán)
    function eachProp(obj, func) {}
    //混合source屬性值(target沒有同名的)到target
    //force為真,target同名覆蓋,deepStringMixin為真,深混合
    function mixin(target, source, force, deepStringMixin) {}
    //返回逆名函數(shù),執(zhí)行為obj調(diào)用fn函數(shù)
    function bind(obj, fn) {}
    //返回script元素的集合
    function scripts() {}
    //throw err;
    function defaultOnError(err) {}
    //例getGlobal("aa.bb");為global.aa.bb
    function getGlobal(value) {}
    //生成一個(gè)錯(cuò)誤
    function makeError(id, msg, err, requireModules) {}
    if (typeof define !== "undefined") {
        return;
    }
    if (typeof requirejs !== "undefined") {
        if (isFunction(requirejs)) {
            return;
        }
        cfg = requirejs;
        requirejs = undefined;
    }
    if (typeof require !== "undefined" && !isFunction(require)) {
        cfg = require;
        require = undefined;
    }
    function newContext(contextName) {
        var inCheckLoaded, Module, context, handlers,
            checkLoadedTimeoutId,
            config = {
                waitSeconds: 7,
                baseUrl: "./",
                paths: {},
                bundles: {},
                pkgs: {},
                shim: {},
                config: {}
            },
            registry = {},
            enabledRegistry = {},
            undefEvents = {},
            defQueue = [],
            defined = {},
            urlFetched = {},
            bundlesMap = {},
            requireCounter = 1,
            unnormalizedCounter = 1;
        //ary中.刪除此項(xiàng);..刪此項(xiàng)和前一項(xiàng)除(i === 0 || (i === 1 && ary[2] === "..") || ary[i - 1]==="..")
        function trimDots(ary) {}
        //路徑處理.config.pkgs有name值優(yōu)先,無值按相對路徑轉(zhuǎn)化,apply是否啟用地圖配置
        function normalize(name, baseName, applyMap) {}
        //刪除data-requiremoduley為name和data-requirecontext === context.contextName的script
        function removeScript(name) {}
        //先移除再加載模塊;
        function hasPathFallback(id) {}
        //第一個(gè)"!"分離的前后數(shù)據(jù) return [prefix, name];
        function splitPrefix(name) {}
        //返回模塊的屬性對象
        // return {
        //         prefix: prefix,
        //         name: normalizedName,
        //         parentMap: parentModuleMap,
        //         unnormalized: !!suffix,
        //         url: url,
        //         originalName: originalName,
        //         isDefine: isDefine,
        //         id: (prefix ?
        //                 prefix + "!" + normalizedName :
        //                 normalizedName) + suffix
        //     };
        function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) {}
        //registry[id]有值取值,沒值生成新的context.Module對象,并賦給registry[id]
        function getModule(depMap) {}
        //模塊加載完且name為defined 或 加載出錯(cuò)且name為error ? 執(zhí)行fn : 模塊綁定事件 
        function on(depMap, name, fn) {}
        //errback ? 執(zhí)行errback(err) : mod.emit("error", err)執(zhí)行刪除操作
        function onError(err, errback) {}
        //將globalDefQueue推入defQueue
        function takeGlobalQueue() {}
        //commonjs風(fēng)格
        handlers = {
            //mod.require ? 返回mod.require : localRequire
            "require": function (mod) {},
            "exports": function (mod) {},
            "module": function (mod) {}
        };
        //清除registry[id]、enabledRegistry[id]
        function cleanRegistry(id) {}
        //遞歸mod.depMaps,執(zhí)行mod.check();
        function breakCycle(mod, traced, processed) {}
        //檢查加載狀態(tài),不同狀態(tài)執(zhí)行不同操作
        function checkLoaded() {}
        Module = function (map) {
            this.events = getOwn(undefEvents, map.id) || {};
            this.map = map;
            this.shim = getOwn(config.shim, map.id);
            this.depExports = [];
            this.depMaps = [];
            this.depMatched = [];
            this.pluginMaps = {};
            this.depCount = 0;
        };
        Module.prototype = {
            //初始化,根據(jù)options.enabled ? this.enable() : this.check()
            init: function (depMaps, factory, errback, options) {},
            //通過this.depCount判斷依賴是否加載完成
            defineDep: function (i, depExports) {},
            // map.prefix ? this.callPlugin() : this.load();
            fetch: function () {},
            //通過context.load調(diào)req.load加載js文件
            load: function () {},
            //define模塊調(diào)用
            check: function () {},
            //加載依賴
            callPlugin: function () {},
            //data-main上的模塊調(diào)用,define模塊調(diào)用
            enable: function () {},
            //將cb推入this.events[name]
            on: function (name, cb) {},
            //name === "error"刪this.events[name];否則循環(huán)this.events[name]執(zhí)行cb(evt);
            emit: function (name, evt) {}
        };
        //module.init內(nèi)執(zhí)行check()非enable();
        function callGetModule(args) {}
        //移除監(jiān)聽事件
        function removeListener(node, func, name, ieName) {}
        //移除監(jiān)聽事件,返回節(jié)點(diǎn)
        function getScriptData(evt) {}
        // 獲取并加載defQueue中的模塊 
        function intakeDefines() {}
        context = {
            config: config,
            contextName: contextName,
            registry: registry,
            defined: defined,
            urlFetched: urlFetched,
            defQueue: defQueue,
            defQueueMap: {},
            Module: Module,
            makeModuleMap: makeModuleMap,
            nextTick: req.nextTick,
            onError: onError,
            //配置參數(shù) 調(diào)用context.require(cfg.deps || [], cfg.callback);
            configure: function (cfg) {},
            //返回閉包接口供調(diào)用
            makeShimExports: function (value) {},
            //返回閉包接口供調(diào)用
            makeRequire: function (relMap, options) {
                //makeRequire的實(shí)際執(zhí)行函數(shù),生成宏任務(wù);
                function localRequire(deps, callback, errback) {
                    return localRequire;
                }
                mixin(localRequire, {
                    isBrowser: isBrowser,
                    toUrl: function (moduleNamePlusExt) {},
                    defined: function (id) {},
                    specified: function (id) {}
                });
                if (!relMap) {
                    localRequire.undef = function (id) {};
                }
                return localRequire;
            },
            //調(diào)用 module的enable()
            enable: function (depMap) {},
            //完成加載后
            completeLoad: function (moduleName) {},
            //根據(jù)moduleName獲取url
            nameToUrl: function (moduleName, ext, skipExt) {},
            //調(diào)用req.load()
            load: function (id, url) {},
            //return callback.apply(exports, args);
            execCb: function (name, callback, args, exports) {},
            //加載完成后
            onScriptLoad: function (evt) {},
            //加載錯(cuò)誤
            onScriptError: function (evt) {}
        };
        context.require = context.makeRequire();
        return context;
    }
    //入口函數(shù)
    req = requirejs = function (deps, callback, errback, optional) {};
    //return req(config);
    req.config = function (config) {};
    //宏任務(wù)
    req.nextTick = typeof setTimeout !== "undefined" ? function (fn) {
        setTimeout(fn, 4);
    } : function (fn) { fn(); };
    //req賦值給require
    if (!require) {
        require = req;
    }
    req.version = version;
    req.jsExtRegExp = /^/|:|?|.js$/;
    req.isBrowser = isBrowser;
    s = req.s = {
        contexts: contexts,
        newContext: newContext
    };
    //初始調(diào)用
    req({});
    each([
        "toUrl",
        "undef",
        "defined",
        "specified"
    ], function (prop) {
        req[prop] = function () {
            var ctx = contexts[defContextName];
            return ctx.require[prop].apply(ctx, arguments);
        };
    });
    if (isBrowser) {
        head = s.head = document.getElementsByTagName("head")[0];
        baseElement = document.getElementsByTagName("base")[0];
        if (baseElement) {
            head = s.head = baseElement.parentNode;
        }
    }
    req.onError = defaultOnError;
    //創(chuàng)建節(jié)點(diǎn)
    req.createNode = function (config, moduleName, url) {};
    //節(jié)點(diǎn)綁定事件,添加到頭部,并返回節(jié)點(diǎn)
    req.load = function (context, moduleName, url) {};
    //返回狀態(tài)為interactive的節(jié)點(diǎn)
    function getInteractiveScript() {}
    //data-main上的值解析賦給cfg
    if (isBrowser && !cfg.skipDataMain) {
        eachReverse(scripts(), function (script) {
            if (!head) {
                head = script.parentNode;
            }
            dataMain = script.getAttribute("data-main");
            if (dataMain) {
                mainScript = dataMain;
                if (!cfg.baseUrl && mainScript.indexOf("!") === -1) {
                    src = mainScript.split("/");
                    mainScript = src.pop();
                    subPath = src.length ? src.join("/")  + "/" : "./";

                    cfg.baseUrl = subPath;
                }
                mainScript = mainScript.replace(jsSuffixRegExp, "");
                if (req.jsExtRegExp.test(mainScript)) {
                    mainScript = dataMain;
                }
                cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript];
                return true;
            }
        });
    }
    //定義模塊的函數(shù)
    define = function (name, deps, callback) {};
    define.amd = {
        jQuery: true
    };
    req.exec = function (text) {};
    //將data-main的值解析代入req函數(shù);
    req(cfg);
}(this, (typeof setTimeout === "undefined" ? undefined : setTimeout)));
二、詳細(xì)流程

1、初始化變量;
2、執(zhí)行 req({})

req({})
context = contexts[contextName] = req.s.newContext(contextName);

說明:contextName="_",返回context這個(gè)東西,context.require = context.makeRequire();=localRequire;調(diào)用makeRequire實(shí)際調(diào)用makeRequire里的localRequire

context.configure(cfg);

說明:cfg=config={},什么都沒干

return context.require(deps, callback, errback);

說明:調(diào)用makeRequire里的localRequire;deps=[];

  intakeDefines();
      takeGlobalQueue();

說明:intakeDefines的子函數(shù),兩者什么都沒執(zhí)行

 context.nextTick(function () {
                        intakeDefines();
                        requireMod = getModule(makeModuleMap(null, relMap));

                        requireMod.skipMap = options.skipMap;
                        requireMod.init(deps, callback, errback, {
                            enabled: true
                        });
                        checkLoaded();
                    });

說明:產(chǎn)生一個(gè) 宏任務(wù)1 函數(shù);req({})函數(shù)完

3、執(zhí)行 req(cfg)
獲取data-main上的值并解析成cfg

req(cfg);

說明:cfg={baseUrl:"data-main解析值1",deps:[data-main解析值2]}

context = getOwn(contexts, contextName);

說明:獲取之前產(chǎn)生的context;

context.configure(cfg);

說明:cfg=config={baseUrl:"data-main解析值1",deps:[data-main解析值2]}

config[prop] = value;

說明:屬性值給config

context.require(cfg.deps || [], cfg.callback);

說明:調(diào)用makeRequire里的localRequire;deps=[data-main解析值2];

intakeDefines();
takeGlobalQueue();

說明:什么都沒執(zhí)行

context.nextTick(function () {

說明:產(chǎn)生一個(gè) 宏任務(wù)2 函數(shù);

return context.require(deps, callback, errback);

說明:調(diào)用makeRequire里的localRequire;deps=[];

intakeDefines();
takeGlobalQueue();

說明:什么都沒執(zhí)行

context.nextTick(function () {

說明:產(chǎn)生一個(gè) 宏任務(wù)3 函數(shù);req(cfg);函數(shù)完

4、第一個(gè)宏任務(wù)開始

intakeDefines();
takeGlobalQueue();

說明:什么都沒執(zhí)行

requireMod = getModule(makeModuleMap(null, relMap));
makeModuleMap(null, relMap)

說明:返回一個(gè)對象obj

nameParts = splitPrefix(name);

說明:name="_@r2"

normalizedName = normalize(name, parentName, applyMap);
url = context.nameToUrl(normalizedName);
parentModule = syms.slice(0, i).join("/");

說明:parentModule="_@r2"

getModule(obj)
new context.Module(depMap)

說明:depMap=上面返回的對象obj;getModule返回context.Module實(shí)例requireMod

requireMod.init(deps, callback, errback, {enabled: true});
this.enable();
enabledRegistry[this.map.id] = this;
this.check();
cleanRegistry(id);
this.emit("defined", this.exports);
checkLoaded();

說明:什么都沒執(zhí)行,第一個(gè)宏任務(wù)完。

5、第二個(gè)宏任務(wù)開始

intakeDefines();
takeGlobalQueue();

說明:什么都沒執(zhí)行

requireMod = getModule(makeModuleMap(null, relMap));
makeModuleMap(null, relMap)

說明:返回一個(gè)對象obj

nameParts = splitPrefix(name);

說明:name="_@r3"

normalizedName = normalize(name, parentName, applyMap);
url = context.nameToUrl(normalizedName);
parentModule = syms.slice(0, i).join("/");

說明:parentModule="_@r3"

getModule(obj)
new context.Module(depMap)

說明:depMap=上面返回的對象obj;getModule返回context.Module實(shí)例requireMod

requireMod.init(deps, callback, errback, {enabled: true});

說明: deps 變?yōu)?data-main解析值2

    this.enable();
        enabledRegistry[this.map.id] = this;
        depMap = makeModuleMap(depMap,(this.map.isDefine ? this.map : this.map.parentMap), false,!this.skipMap);
            nameParts = splitPrefix(name);
            normalizedName = normalize(name, parentName, applyMap);                                
            url = context.nameToUrl(normalizedName);                           
"        on(depMap, "defined", bind(this, function (depExports) {this.defineDep(i, depExports);this.check();}));
                            
                            
                        "
            mod = getModule(depMap);
                mod = registry[id] = new context.Module(depMap);
            mod.on(name, fn);
            getModule(depMap).enable();
        this.check();
checkLoaded();

說明: 宏任務(wù)2結(jié)束

6、宏任務(wù)3同宏任務(wù)1

7、執(zhí)行data-main引入的文件的require函數(shù)

require(["./example"],function(example){example.test();});
req = requirejs = function (deps, callback, errback, optional) {
    return context.require(deps, callback, errback);
        intakeDefines();
            takeGlobalQueue();
                context.nextTick(function () {

說明: 產(chǎn)生一個(gè)宏任務(wù)4函數(shù);require函數(shù)結(jié)束

onScriptLoad: function (evt) {
    var data = getScriptData(evt);
    context.completeLoad(data.id);
        shim = getOwn(config.shim, moduleName) || {},
        takeGlobalQueue();
        callGetModule([moduleName, (shim.deps || []), shim.exportsFn]);

說明: require函數(shù)結(jié)束后執(zhí)行

8、宏任務(wù)4同宏任務(wù)2
說明: deps變?yōu)?要加載的依賴

三、流程相關(guān)圖片

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/107357.html

相關(guān)文章

  • 前端模塊化和構(gòu)建工具

    摘要:以前一直對前端構(gòu)建工具的理解不深,經(jīng)過幾天的研究特意來總結(jié)一下,第一次寫博客,有寫錯(cuò)的請多多見諒,該文章我也從其他博客拷了一些內(nèi)容,如果有冒犯之處,請指出。強(qiáng)大的設(shè)計(jì)使得它更像是一個(gè)構(gòu)建平臺(tái),而不只是一個(gè)打包工具。 以前一直對前端構(gòu)建工具的理解不深,經(jīng)過幾天的研究特意來總結(jié)一下,第一次寫博客,有寫錯(cuò)的請多多見諒,該文章我也從其他博客拷了一些內(nèi)容,如果有冒犯之處,請指出。 如今,網(wǎng)頁不再...

    ad6623 評(píng)論0 收藏0
  • RequireJS:一款優(yōu)秀的AMD模塊加載器

    摘要:概述是一款遵循規(guī)范協(xié)議的模塊加載器,不但能在瀏覽器端充分利用,同樣能在其他的運(yùn)行時(shí)環(huán)境,比如和。使用像這樣的模塊加載器能提高代碼的質(zhì)量和開發(fā)速度。一般放在頁面的入口出,用來加載其他的模塊。 RequireJS概述 RequireJS是一款遵循AMD規(guī)范協(xié)議的JavaScript模塊加載器, 不但能在瀏覽器端充分利用,同樣能在其他的JavaScript運(yùn)行時(shí)環(huán)境, 比如Rhino和No...

    syoya 評(píng)論0 收藏0
  • seajs 源碼解讀

    摘要:本文主要簡單地解讀一下的源碼和模塊化原理。其中,是這次源碼解讀的核心,但我也會(huì)順帶介紹一下其他文件的作用的。對代碼比較簡單,其實(shí)就是聲明一下全局的命名空間。然而,真正的核心在于處理模塊依賴的問題。 seajs 簡單介紹 seajs是前端應(yīng)用模塊化開發(fā)的一種很好的解決方案。對于多人協(xié)作開發(fā)的、復(fù)雜龐大的前端項(xiàng)目尤其有用。簡單的介紹不多說,大家可以到seajs的官網(wǎng)seajs.org參看...

    LiangJ 評(píng)論0 收藏0
  • requirejs的插件介紹與制作

    摘要:一句化即它是插件的插件,作者事后才發(fā)現(xiàn)有這么一個(gè)插件繞了不少彎路。這里的主要是為了保存這段內(nèi)容用于打包使用。免費(fèi)領(lǐng)取驗(yàn)證碼內(nèi)容安全短信發(fā)送直播點(diǎn)播體驗(yàn)包及云服務(wù)器等套餐更多網(wǎng)易技術(shù)產(chǎn)品運(yùn)營經(jīng)驗(yàn)分享請?jiān)L問網(wǎng)易云社區(qū)。文章來源網(wǎng)易云社區(qū) 本文由作者鄭海波授權(quán)網(wǎng)易云社區(qū)發(fā)布。 前言我這里就不介紹requirejs了, 簡而言之: requirejs是支持AMD規(guī)范的模塊加載器, 事實(shí)上它也是...

    shinezejian 評(píng)論0 收藏0
  • 從 IIFE 聊到 Babel 帶你深入了解前端模塊化發(fā)展體系

    摘要:我覺得那時(shí)他可能并沒有料到,這一規(guī)則的制定會(huì)讓整個(gè)前端發(fā)生翻天覆地的變化。前言 作為一名前端工程師,每天的清晨,你走進(jìn)公司的大門,回味著前臺(tái)妹子的笑容,摘下耳機(jī),泡上一杯茶,打開 Terminal 進(jìn)入對應(yīng)的項(xiàng)目目錄下,然后 npm run start / dev 或者 yarn start / dev 就開始了一天的工作。 當(dāng)你需要進(jìn)行時(shí)間的轉(zhuǎn)換只需要使用 dayjs 或者 momentj...

    tinylcy 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<