Requirejs - 定义中的模块有时(并非总是)未定义

时间:2015-01-06 23:26:17

标签: javascript requirejs amd

UPD:问题通过将RequireJS 2.1.15更改为2.0来解决。

在我的代码中找到问题几天后(使用谷歌)我决定写在这里。 我有客户端JS,它使用requirejs作为架构的基础。但有时这个系统不正常,我看到'define'中列出的模块有时会返回未定义的值,这是导致我的应用程序崩溃的原因。但事实并非总是如此,平均每5页重新加载以及系统的不同部分。下面我附上了真实的项目结构和可以抛出错误的文件代码。

结构: https://cloud.githubusercontent.com/assets/1973760/5637730/02370346-9629-11e4-88ef-00dfea7a5e1c.png

app.js

requirejs.config({
    paths: {
        jquery: 'Lib/jquery-1.11.0.min',
        socketio: 'http://localhost:81/socket.io/socket.io',
        jquerytmpl: 'Lib/jquery.tmpl.min',
        jqueryui: 'https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min',
        jquerymultiselect: 'Lib/jquery-ui/jquery.multiselect.min',
        css: 'Lib/requirecss',
        cookie: 'Lib/jquery.cookie',
        bootstrap: "http://netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min",
        flatui: "Lib/flat-ui-pro.min"
    },
    waitSeconds: 200,
    shim: {
        socketio: {
            exports: 'io'
        },
        flatui: {
            exports: '$',
            deps: ['jquery']
        },
        cookie: {
            exports: '$',
            deps: ['jquery']
        }
    }
});
require(['jquery', 'Router'], function($, Router){
    Router.startRouting();
});

Router.js

define(['jquery'], function($) {
    var routes = [{uri: /^\/$/, controller: 'MainPageController'},
        {uri: /^\/[a-z0-9_]+\/?$/, controller: 'PublicPageController'},
        {uri: /^\/public\/add\/?$/, controller: 'PublicAddPageCOntroller'}];

    function startRouting() {
        var currentURI = window.location.pathname;

        $.each(routes, function(k, v) {
            if (v.uri.test(currentURI)) {
                loadController(v.controller);
            }
        });
    }

    function loadController(controllerName) {
        require(['Controllers/' + controllerName], function(controller) {
            controller.init();
        });
    }

    return {
        startRouting: startRouting
    };
});

控制器/ PublicPageController.js

define(['jquery', 'socketio', 'Modules/ChatModule', 'Modules/NotificationModule', 'Modules/StatusModule', 'Modules/PageBuilderModule', 'Entity/Mediator'], function ($, io, ChatModule, NotificationModule, StatusModule, PageBuilderModule, mediator) {
    function init() {
        /**
         * Connect to socket.io server
         */
        var socket = io('http://localhost:81/?token=' + token);
        /**
         * init modules
         */
        var notificationModule = new NotificationModule(socket, mediator);
        var pageBuilderModule = new PageBuilderModule(socket, mediator);
        var chatModule = new ChatModule(socket, mediator);
        var statusModule = new StatusModule(socket, mediator);

    }
    return {init: init};
});

模块/ NotificationModule.js

define(['jquery', 'Entity/SystemNotification', 'Entity/ChatRequestNotification', 'Entity/Notifications', 'Entity/ChatRequestNotificationAcceptedByPair', 'Entity/UriModifier'], function ($, SystemNotification, ChatRequestNotification, Notifications, ChatRequestNotificationAcceptedByPair, UriModifier) {

    function NotificationModule(socket, mediator) {
        var notifications = new Notifications(socket);
        var that = this;
        this.addNotification = function (data) {
            switch (data.type) {
                case 1:
                    var notification = new SystemNotification(data.id, data.fields.message, data.fields.from, socket);
                    break;
                case 2:
                    var notification = new ChatRequestNotification(data.id, data.fields.from, UriModifier.getCurrentSlug(), socket,
                            function (err, data) {
                                mediator.publish('chatRequestAccepted', err, data, notification);
                            },
                            function (err, data) {
                                mediator.publish('chatRequestDeclined', err, data, notification);
                            });
                    break;
                case 3:
                    var notification = new ChatRequestNotificationAcceptedByPair(data.id, data.fields.from, socket,
                            function (err, data) {
                                mediator.publish('chatRequestStarted', err, data, notification);
                            }, function (err, data) {
                                //chatRequestCanceled
                                mediator.publish('chatRequestCanceled', err, data, notification);
                            });
                    break;
            }
            if(notification){
                notifications.push(notification);
            }

        };

        socket.on('notificationsLoaded', function (data) {
            $.each(data.notifications, function (k, v) {
                that.addNotification(v);
            });
        });
    }
    return NotificationModule;

});

实体/ SystemNotification

define(['jquery','Entity/Notification','Views/SystemNotificationView'], function ($, Notification, SystemNotificationView) {
    function SystemNotification(id, message, from, socket) {
        var parent = Notification.call(this, id, socket);
        parent.setView(new SystemNotificationView(id, 'Системное уведомление', message, from));
    };

    return SystemNotification;
});

实体/通知

define(['jquery'], function ($) {
    return function (id, socket) {
        var that = this;
        this.append = function () {
            this.view.append();
        };
        this.close = function () {
            this.view.close();
            socket.emit('closeNotification', {id: id});
        };
        this.getId = function () {
            return id;
        };

        return {
            setView: function (v) {
                that.view = v;
                $(that.view).on('close', function () {
                    that.close();
                });
            }
        };
    };
});

的index.html

<script data-main="/app" src="/Lib/requirejs.js"></script>

下一步是执行流程:

  • app.js init requrejs options并运行Router.js
  • 路由器检测当前页面并运行适合的控制器(在此示例中为PublicPageController)
  • 在控制器中运行模块(注意NotificationModule)
  • 通知模块为socketio事件'notificationsLoaded'注册回调,返回通知数据。在已注册的回调中,NotificationModule尝试创建通知对象(例如Entity / SystemNotification)。每个通知它是基类实体/通知
  • 的子代
  • 在Entity / SystemNotification构造函数中,我尝试调用var parent = Notification.call(this,id,socket);继承实现,但有时通知是未定义的!这是问题。

上面仅针对1例错误进行了描述,还有更多地方我有相同的错误(未定义模块)

我的requirejs版本是RequireJS 2.1.15

请帮帮我,问题出在哪里?

此致 安德烈·沃罗比奥夫

UDPATE: 如果我改变了

,我会看到同样的错误
var parent = Notification.call(this, id, socket);

var parent = require('Entity/Notification').call(this, id, socket);

0 个答案:

没有答案