ege*_*ari 54 javascript singleton requirejs
假设我在主页面级别编写代码,并且2个依赖项需要对象的相同实例,并且还将其声明为依赖项.适当的方法是什么?
基本上我想要做的就是说,"如果没有加载这个依赖...然后加载它.否则,使用已加载的同一个实例,然后传递那个."
Dom*_*nic 58
你会把它变成一个模块级变量.例如,
// In foo.js
define(function () {
var theFoo = {};
return {
getTheFoo: function () { return theFoo; }
};
});
// In bar.js
define(["./foo"], function (foo) {
var theFoo = foo.getTheFoo(); // save in convenience variable
return {
setBarOnFoo: function () { theFoo.bar = "hello"; }
};
}
// In baz.js
define(["./foo"], function (foo) {
// Or use directly.
return {
setBazOnFoo: function () { foo.getTheFoo().baz = "goodbye"; }
};
}
// In any other file
define(["./foo", "./bar", "./baz"], function (foo, bar, baz) {
bar.setBarOnFoo();
baz.setBazOnFoo();
assert(foo.getTheFoo().bar === "hello");
assert(foo.getTheFoo().baz === "goodbye");
};
Run Code Online (Sandbox Code Playgroud)
只需像您一样为您的单身人士提供API.
并确保它懒洋洋地加载.最简单的方法是使用像下划线那样提供跨浏览器帮助程序的抽象库.其他选项是ES5 Object.defineProperty或自定义getter/setter.
在这种情况下,_.once
确保构造函数的结果在第一次调用后被缓存,它基本上是懒惰加载它.
define(function() {
var constructor = _.once(function() {
...
});
return {
doStuffWithSingleton: function() {
constructor().doStuff();
}
};
});
Run Code Online (Sandbox Code Playgroud)
_.once
从下划线.
结合Raynos对封装的担忧和OP的澄清,他希望在消息服务上公开几种方法,这是我认为正确的方法:
// In messagingServiceSingleton.js
define(function () {
var messagingService = new MessagingService();
return {
notify: messagingService.listen.bind(messagingService),
listen: messagingService.notify.bind(messagingService)
};
});
// In bar.js
define(["./messagingServiceSingleton"], function (messagingServiceSingleton) {
messagingServiceSingleton.listen(/* whatever */);
}
// In baz.js
define(["./messagingServiceSingleton"], function (messagingServiceSingleton) {
messagingServiceSingleton.notify(/* whatever */);
}
Run Code Online (Sandbox Code Playgroud)
Function.prototype.bind
将不会出现在所有浏览器中,因此您需要包含像Mozilla提供的那样的 polyfill .
备用(在我看来可能更好)的方法是使消息传递服务对象本身成为一个模块.这看起来像
// In messagingService.js
define(function () {
var listenerMap = {};
function listen(/* params */) {
// Modify listenerMap as appropriate according to params.
}
function notify(/* params */) {
// Use listenerMap as appropriate according to params.
}
return {
notify: notify
listen: listen
};
});
Run Code Online (Sandbox Code Playgroud)
既然你公开相同notify
和listen
谁使用你的模块的方法给大家,和那些总是指向同一个私有 listenerMap
变量,这应该做你想做的.它还消除了Function.prototype.bind
对消息传递服务本身和强制单独使用它的模块之间相当不必要的区别的需要和消除.
归档时间: |
|
查看次数: |
31763 次 |
最近记录: |