seajsモジュール間の相互依存呼び出しのデカップリング問題について
5597 ワード
フロントエンド密集型項目では、データ同期の量が大きい場合、複数のコンポーネントに対してデータ同期を行う必要があり、いくつかのコンポーネント間の相互依存呼び出しが必ず発生し、seajsで入れ子の呼び出しコンポーネントが循環参照を引き起こしてメモリリークを引き起こす.
たとえば、このような二つのモジュールコンポーネントがあります.
backboneモジュール間通信モードを参考にした後、中間部品の方法を注入してモジュール間通信を担当することができます.中間部品を導入:
上のコードのように方法の注入と方法のトリガを行い、friend-inn-groupにaddとremoveを登録する方法イベントは、add-friendで方法イベントのトリガを行います.subscribevent方法では、匿名方法を中間モジュールに転送し、この匿名関数は、argに登録コンポーネントの着信データを保存し、パラメータdata
モジュール側の着信パラメータをトリガし、登録モジュール側でこのモジュールのプライベート関数を参照することは、この匿名関数のクローズド・ロール範囲を登録モジュール内部に拡張することに相当する.このようにして、イベントをトリガするときにモジュールを登録するすべての参照状態を保持することができる.デカップリングの効果を発揮した.
たとえば、このような二つのモジュールコンポーネントがあります.
//@file : module/buddy/friend-in-group/friend-in-group.js
define(function(require, exports, module){
var $ = require('lib/jquery.js'),
_ = require('lib/underscore.js'),
friend = require('module/buddy/add-friend/add-friend');
var _addFriend = function(){
// Some logic here
};
var _removeFriend = function(uid){
// Some logic here
};
exports.addFriend = function(uid){
// Some logic here
_addFriend(uid,false);
};
exports.removeFriend = function(uid){
// Some logic here
_removeFriend(uid,false);
};
exports.init = function(){
// Some logic here
friend.add();
}
});
//@file : module/buddy/add-friend/add-friend.js
define(function(require, exports, module){
var $ = require('lib/jquery.js'),
_ = require('lib/underscore.js'),
fig = require('module/buddy/friend-in-group/friend-in-group');
var itemClickAction = function(){
var increase;
// Some logic here
if(increase === 1){
fig.addFriend(uid,gid);
}else{
fig.removeFriend(uid,gid);
}
};
exports.add = function(){
// Some logic here
itemClickAction();
}
});
このような2つのモジュール・コンポーネント、friend-inn-groupコンポーネントとadd-friendコンポーネント、friend-inn-groupコンポーネントは、いくつかのUIニーズのために、add-friendコンポーネントを呼び出す必要がありますが、friend-inn-groupコンポーネントが露出している2つの方法addFriendとremoveFriendは、他のモジュールのデータを同期するために使用されます.ちょうどadd-friendでは、itemClickAction方法を実行すると、ユーザの動作によってデータ同期動作が発生するので、friend-i-group露出を呼び出す2つの方法が必要である.このように、クローズドの循環呼び出しが発生しました.seajsでは直接エラーが発生します.この二つのモジュールをどうやって結合しますか?単例モードのモジュールであれば、直接イベント登録の方法を採用して内部で解決できますが、例えばadd-friendというモジュールは単例ではなく、重用度が大きいですか?この問題はプロジェクトの中では確かに面倒くさいことです.backboneモジュール間通信モードを参考にした後、中間部品の方法を注入してモジュール間通信を担当することができます.中間部品を導入:
define(function(require, exports, module){
var $ = require('lib/jquery');
var _ = require('lib/underscore');
var events = {};
exports.subscribe = function(type,fn,arg){
if(!events[type]){
events[type] = {};
}
events[type] = {
fn:fn,
arg:arg
};
};
exports.unsubscribe = function(type){
if(!events[type] || !type ){
return false;
}
if(!!events[type]){
events[type] = {};
return true;
}
return false;
};
exports.fire = function(type,data){
if(events[type]){
events[type].fn(data,events[type].arg);
}
};
});
このモジュールは、まず、2つのモジュールを結合するいずれかの一方を導入することなく、結合を低減する.主なのは露出された登録方法とフリップフロップ方法であり、これはfriend-inn-group方法において中間部品にaddFriendとremoveFriend方法を注入してからadd-friendコンポーネントにトリガすることができ、ここで再帰的な循環呼出しが形成されない.//@file : module/buddy/friend-in-group/friend-in-group.js
define(function(require, exports, module){
var $ = require('lib/jquery.js'),
_ = require('lib/underscore.js'),
fmw = require('module/buddy/friend-in-group/friend-middleware'),
friend = require('module/buddy/add-friend/add-friend');
var _addFriend = function(){
// Some logic here
};
var _removeFriend = function(uid){
// Some logic here
};
var subscribeEvent = function(){
fmw.subscribe('add',function(data,arg){
// Some logic here
_addFriend(uid,false);
},[currentGroupId]);
fmw.subscribe('remove',function(data,arg){
// Some logic here
_removeFriend(uid);
},[currentGroupId]);
}
exports.init = function(){
// Some logic here
friend.add();
}
});
//@file : module/buddy/friend-in-group/friend-in-group.js
define(function(require, exports, module){
var $ = require('lib/jquery.js'),
_ = require('lib/underscore.js'),
fmw = require('module/buddy/friend-in-group/friend-middleware'),
friend = require('module/buddy/add-friend/add-friend');
var _addFriend = function(){
// Some logic here
};
var _removeFriend = function(uid){
// Some logic here
};
var subscribeEvent = function(){
fmw.subscribe('add',function(data,arg){
// Some logic here
_addFriend(uid,false);
},[currentGroupId]);
fmw.subscribe('remove',function(data,arg){
// Some logic here
_removeFriend(uid);
},[currentGroupId]);
}
exports.init = function(){
subscribeEvent();
friend.add();
}
});
上のコードのように方法の注入と方法のトリガを行い、friend-inn-groupにaddとremoveを登録する方法イベントは、add-friendで方法イベントのトリガを行います.subscribevent方法では、匿名方法を中間モジュールに転送し、この匿名関数は、argに登録コンポーネントの着信データを保存し、パラメータdata
モジュール側の着信パラメータをトリガし、登録モジュール側でこのモジュールのプライベート関数を参照することは、この匿名関数のクローズド・ロール範囲を登録モジュール内部に拡張することに相当する.このようにして、イベントをトリガするときにモジュールを登録するすべての参照状態を保持することができる.デカップリングの効果を発揮した.