知道OSC Javascript大神多,请教个实现的思路

Solowave 发布于 2014/03/13 14:20
阅读 476
收藏 2
144行那里,我怎么写才能把实例返回给外部调用者呢????

就是把 doEntity的返回的内容再return下。。。。。。唉,也不知道该怎么描述的说。。。。

(function (window) {
    //申明以 ES5严格标准运行框架
    "use strict";

    /**
     * 一些模块内部的属性
     * @var {Object} moduleMap 已载入的模块定义
     * @var {Object} pathMap 已载入的模块文件物理路径
     * @var {Function} noop 空函数
     * @var {Object} runtime 运行时寄存器
     */
    var moduleMap = {},
        pathMap   = {},
        noop      = function () {
            return undefined;
        },
        runtime   = {
            moduleRoot: "http://localhost/pi/application/www/js/vendor/module/"
        };

    /**
     * 对外公开的所有可供使用的框架功能接口
     */
    window.danJs = {
        /**
         * 定义和注册模块信息
         * 供模块调用,使用者不应该调用此方法
         * @param {String} name 模块的名称
         * @param {Array}  dependencies 模块依赖哪些其他模块
         * @param {Object} method 模块的工厂方法和自运行的启动脚本、销毁脚本等
         * @return {Array} 模块注册的信息
         */
        define: function (name, dependencies, method) {
            //是否已经载入过了,
            //如果是则直接返回该模块的信息
            //如果否则将新的模块信息压入已注册模块列表
            if (!moduleMap[name]) {
                var module = {
                    name: name,
                    dependencies: dependencies,
                    factory: method.factory
                };
                moduleMap[name] = module;
                //运行模块的预定义程序,如果有
                method.init && method.init();
            }
            //返回注册的信息
            return moduleMap[name];
        },
        /**
         * 异步加载一个模块
         * @param {Mixed} modules 模块的名称(列表)
         * @param {Function} callback 回调函数,当所有模块
         *     被载入后,此函数会被执行
         */
        require: function (modules, callback) {
            var module, j = 0;
            //先格式化一下给定的模块名
            modules = this.extend.isArray(modules) ? 
                    modules :
                    typeof modules === "string" && [modules]
                || [];

            //定义一个用来检查模块是否已经全部注册的回调函数,
            //如果检查所有的文件都被载入,则执行回调函数。
            function checkLoaded() {
                var allLoaded = true;
                for (var i = 0, len = modules.length; i< len; i++) {
                    if (!pathMap[modules[i]]){
                        allLoaded = false;
                        break;
                    }
                }
                //如果所有模块被判定都已经载入,
                //且回调函数存在,则执行回调函数。
                (allLoaded && callback) && callback();
            };

            //遍历每个需要加载的模块,以异步载入
            while (module = modules[j++]){
                //检查是否是一个已经载入的模块
                //如果是我们将跳过此模块否则加载之
                if (!pathMap[module]){
                    //在HEAD中插入一个script标签,以便让浏览器
                    //开始下载该模块的文件,我们会在完成工作后删除这一标签
                    var scriptNode = document.createElement("script");
                    scriptNode.id = module;
                    scriptNode.type = "text/javascript";
                    scriptNode.async = "true";
                    scriptNode.src = this.runtime("moduleRoot")+ module+ ".js";
                    scriptNode.onload = function(){
                        //如果运行到这里,以为这单个模块已经加载成功,那么:
                        //将加载状态标记为成功
                        //移除script标签
                        //调用在上面定义的检查所有模块是否都已载入的函数
                        debugger;
                        pathMap[this.id] = true;
                        document.head.removeChild(this);
                        checkLoaded();
                    };
                    document.head.appendChild(scriptNode);
                }
            }
        },
        /**
         * 对外部返回模块的实例
         * @param {String} name 要请求的模块名称
         * @return {Mixed} 视模块的工厂而定,此返回地类型可能为任意类型
         *     但大多部分情况下,很可能是个包含多种方法的类或仅仅是个函数
         */
        use: function (name) {
            //我们先定义一个仅在模块已定义的情况下才会运行的函数
            //这个函数会返回一个请求模块的实际实例
            //这样做的目的是为了对于没有载入的模块可以在这里实现异步加载
            function doEntity() {
                var module = moduleMap[name];
                //检查模块是否已经生成过实例
                if (!module.entity){
                    //运行到这里意味着模块的实例尚未生成,
                    //那么先遍历检查它的每个依赖模块的实例是否已经生成是很有必要的
                    var args = [];
                    for (var i = 0, len = module.dependencies.length; i< len; i++){
                        //检查单个所依赖的模块的实例是否已经生成过了,
                        //如果没有则先 生成它后压入args
                        //如果有则直接压入上面定义的args,我们最后将会把arg当作module工厂方法的参数
                        if (!moduleMap[module.dependencies[i]].entity)
                            args.push(this.use(module.dependencies[i]));
                        else
                            args.push(moduleMap[module.dependencies[i]].entity);
                    }
                    //最后生成该模块的实例,并将在上面生成的它所依赖的模块的实例挂载一下
                    //当然我们利用一个空函数以期解决this指针的指向
                    module.entity = module.factory.apply(noop, args);
                }
                
                //返回模块的实例
                return module.entity;
            }

            //在已载入的模块列表中搜索,以检查该模块是否已载入
            //如果尚没有载入,则执行require异步载入,载入后再执行下面的工作
            //如果已载入,则尝试寻找该模块的实例
            if (!moduleMap[name]) {
                this.require(name, doEntity));
            } else
                return doEntity();

            /**
             * @deprecated 0.1-dev
            var module = moduleMap[name];
            //模块的实体是否已经初始化
            if (!module.entity) {
                var args = [];
                for (var i=0; i<module.dependencies.length; i++){
                    if (moduleMap[module.dependencies[i]].entity){
                        args.push(moduleMap[module.dependencies[i]].entity);
                    }else {
                        args.push(this.use(module.dependencies[i]));
                    }
                }
                module.entity = module.factory.apply(noop, args);
            }
            return module.entity;
            **/
        },
        /**
         * 批量式的返回模块实例
         */
        groupUse: function (groups) {
        },
        /**
         * 销毁模块的定义
         */
        unload: function () {
        },
        /**
         * 获取已载入的模块列表
         */
        getModules: function () {
            //list modules
        },
        /**
         * 覆写javascript的原生对象方法以期获得兼容性
         */
        extend: function (name) {
            //add or overwrite methods for compatibility
        },
        /**
         * 从运行时寄存器中取得数据
         */
        runtime: function (index) {
            return runtime[index];
        }
    };
    //initiate runtime parameters for outer reference
    var userAgent = navigator.userAgent.toLowerCase(),
        s;
    runtime.browser = {};
    (s = userAgent.match(/msie ([\d.]+)/))? runtime.browser.ie = s[1]:
    (s = userAgent.match(/firefox\/([\d.]+)/))? runtime.browser.firefox = s[1]:
    (s = userAgent.match(/chrome\/([\d.]+)/))? runtime.browser.chrome = s[1]:
    (s = userAgent.match(/opera.([\d.]+)/))? runtime.browser.opera = s[1]:
    (s = userAgent.match(/version\/([\d.]+).*safari/))? runtime.browser.safari = s[1]: 0;
})(window);

danJs.define("bin", [], {
    /**
     * Public library for modules
     */
    init: function () {
        window.bin = danJs.extend = danJs.use("bin");
    },
    factory: function () {
        return {
            isWindow: function(obj) {
                return obj != null && obj.window == window;
            },
            isArray: function (obj) {
                return Object.prototype.toString.call(obj) == "[object Array]";
            },
            isEmptyObject: function (obj) {
                var name;
                for (name in obj) {
                    return false;
                }
                return true;
            },
            isNumeric: function (obj) {
                return obj - parseFloat(obj) >= 0;
            },
            clearWhite: function(oEelement){
                //clear white space nodes in firefox and webkit based browsers
                for(var i = 0; i < oEelement.childNodes.length; i++){
                    var node = oEelement.childNodes[i];
                    if(node.nodeType == 3 && !/\S/.test(node.nodeValue)){
                        node.parentNode.removeChild(node)
                    }
                }
            },
            insertAfter: function (newEl, targetEl) {
                //opposite to insertbefore
                var parentEl = targetEl.parentNode;
                if (parentEl.lastChild == targetEl){
                    parentEl.appendChild(newEl);
                }else {
                    parentEl.insertBefore(newEl, targetEl.nextSibling);
                }            
            },
            htmlEncode: function (str) {
                var s = "";
                if (str.length == 0) return "";
                s = str.replace(/</g, "&lt;");
                s = s.replace(/>/g, "&gt;");
                s = s.replace(/ /g, "&nbsp;");
                s = s.replace(/\'/g, "&#39;");
                s = s.replace(/\"/g, "&quot;");
                s = s.replace(/\n/g, "<br>");
                return s;
            },
            htmlDecode: function (str) {
                var s = "";
                if (str.length == 0) return "";
                s = str.replace(/&lt;/g, "<");
                s = s.replace(/&gt;/g, ">");
                s = s.replace(/&nbsp;/g, " ");
                s = s.replace(/&#39;/g, "\'");
                s = s.replace(/&quot;/g, "\"");
                s = s.replace(/<br>/g, "\n");
                return s;
            },
            trim: function (ct) {
                return ct.replace(/^\s+|\s+$/g, "");
            }
        };
    }
 });



加载中
0
Solowave
Solowave
不想这么被无视。
0
0x0001
0x0001
用异步的思路,在调用这个东西的时候接受一个回调函数,等待条件满足了就call一下,这样对方就知道你什么时候该返回了。我没有看完你的源码,不知道能不能解决这个问题
Solowave
Solowave
doEntity就是传递给require的回调,现在是我先把doentity的返回再返回给require的调用者
Solowave
Solowave
我有用回调呢,但是现在的问题是怎么把回调里的返回值再次返回呢
0
0x0001
0x0001
doentry不返回东西,接受回掉应该就好了吧
Solowave
Solowave
那这样我就得外部的调用者的代码都要改了,好不划算。
0
陈亦
陈亦
发送事件通知,外部只需监听
Solowave
Solowave
回复 @陈一回 : 非常感谢你
陈亦
陈亦
回复 @Solowave : http://my.oschina.net/goal/blog/200100
Solowave
Solowave
回复 @陈一回 : 将事件注册到哪里呢
陈亦
陈亦
回复 @Solowave : 事件监听只不过是将待执行方法放入队列,怎么会一直卡在这里呢?只有在需要执行的时候才会被执行(触发事件)。
Solowave
Solowave
不是很懂呢。方便的话可以构造个简单的例子么 我的理解是。如果外部要监听这个事件,会不会代码会一直卡在那里呢
0
云香水识
云香水识

45行处, 完全没必要这样做吧。 AMD规范defined模块的时候这个method通常是一个方法的咯。 

你直接让 moduleMap[name] = method( require, module ) || module; 

在method方法里面将需要的对象返回给moduleMap就可以了啊(当然也可以是function)。 

Solowave
Solowave
moduleMap[name] = method( require, module ) || module 这里的 method( require, module ) 是什么意思
0
开源无憾
开源无憾
代码好熟,是楼主的杰作么
Solowave
Solowave
参照别人的实现,加了点自己的东西,结果就这样了
0
gnefil.nil
gnefil.nil

又想异步又想同步,无解

Solowave
Solowave
嘿嘿,我也觉得自己好笨呢
0
自由之信
自由之信

如果是,this.require(name, doEntity)); 想要返回:

use : function (name, callback) {
    ......
    ......
    // have to use callback as its async callback
    this.require(name, function () {
        callback & callback (doEntity());
    }

}

自由之信
自由之信
回复 @Solowave : 嘿嘿~属于文盲会说会听那种
Solowave
Solowave
感觉你英语不错哟
返回顶部
顶部