在 Javascript 中实现一种委托模式
Implementing kind of a delegation pattern in Javascript
我有两个 class,A
和 B
。我想要做的是在收到来自套接字的消息后将数据从 A
传递到 B
。
这是 classes 定义的简化外观:
class答:
export default class A {
client;
callbacks;
constructor() {
this.callbacks = {
open: () => this.client.logger.debug('open'),
close: () => this.client.logger.debug('closed'),
message: (data) => {this.client.logger.log(data)}, //I want to pass this data object to class B
};
this.client = new Spot(constants.apiKey, constants.apiSecret, {
baseURL: constants.baseURL,
wsURL: constants.wsURL,
});
this.client.userData(listenKey, this.callbacks);
}
}
我已经在 class B 的定义中有一个 属性 A:
export default class B {
account;
constructor() {
this.account = new A();
}
}
连接这两者的 correct/standard 方法是什么,所以每次 class A 的套接字消息回调是,我都会从 class A 得到一个 'data' 对象触发了吗?
我对 JS
有点陌生,但在 iOS
上,我们会使用委托模式和协议,上面写着:
- class
A
将有一个代表 属性.
- 委托 (class
B
) 必须实现协议(在这种情况下,需要实现名为 didReceiveMessage(data)
的方法。
- 在那之后,当在 class
A
中收到消息时,我们将(在上面显示的套接字消息回调中)像 this.delegate.didReceiveMessage(data).
这里的协议使用一般来说并不重要,但它是一个加号,因为从 A
class,我们只能通过委托 属性 访问 didReceiveData(data)
方法,仅此而已( class B 的其他属性/方法不可见)。至少在 Swift/Obj-C
中是这样。我刚刚提到了它,因为我很好奇它在 JS 中也是如何完成的。
我想 Javascript
中有一些类似的机制,或者更多 standard/better 方法来实现这种对象之间的数据发送?
我不是 NodeJs 专家,但你可以使用类似 emitter plugin.
的东西
在 javascript 中,它看起来像这样:
function A() {
Emitter(this);
this.action = function() {
console.log("something happened");
this.emit("action", { prop: "value" });
};
}
function B(a_instance) {
// subscribe to "action" event
a.on("action", function(data) {
console.log(data.prop); // "value"
});
};
var myA = new A();
var myB = new B(myA);
myA.action();
on iOS we would use a delegation pattern, with a protocol
你完全可以按照你描述的去做:
export default class A {
client;
delegate;
constructor(delegate) {
this.delegate = delegate;
this.client = new Spot(constants.apiKey, constants.apiSecret, {
baseURL: constants.baseURL,
wsURL: constants.wsURL,
});
const callbacks = {
open: () => this.client.logger.debug('open'),
close: () => this.client.logger.debug('closed'),
message: (data) => this.delegate.didReceiveMessage(data),
};
this.client.userData(listenKey, callbacks);
}
}
export default class B {
account;
constructor() {
this.account = new A(this);
}
didReceiveMessage(data) {
console.log(data); // or whatever
}
}
没有接口(协议)声明可以告诉 A
它可以在传递的 delegate
上访问哪些属性和方法,但合同当然存在。你应该用散文来记录它。 (或使用 TypeScript)。
另请注意您的 class A
如何与 Spot
客户端交互,它使用与事件处理程序方法传递对象非常相同的模式。
如果您的协议中只需要一个方法,JavaScript 中的一个更简单的模式就是只传递一个可调用函数:
export default class A {
client;
constructor(onMessage) {
this.client = new Spot(constants.apiKey, constants.apiSecret, {
baseURL: constants.baseURL,
wsURL: constants.wsURL,
});
this.client.userData(listenKey, {
open: () => this.client.logger.debug('open'),
close: () => this.client.logger.debug('closed'),
message: onMessage,
});
}
}
export default class B {
account;
constructor() {
this.account = new A(this.didReceiveMessage.bind(this));
// or inline:
this.account = new A(data => {
console.log(data); // or whatever
});
}
didReceiveMessage(data) {
console.log(data); // or whatever
}
}
我有两个 class,A
和 B
。我想要做的是在收到来自套接字的消息后将数据从 A
传递到 B
。
这是 classes 定义的简化外观:
class答:
export default class A {
client;
callbacks;
constructor() {
this.callbacks = {
open: () => this.client.logger.debug('open'),
close: () => this.client.logger.debug('closed'),
message: (data) => {this.client.logger.log(data)}, //I want to pass this data object to class B
};
this.client = new Spot(constants.apiKey, constants.apiSecret, {
baseURL: constants.baseURL,
wsURL: constants.wsURL,
});
this.client.userData(listenKey, this.callbacks);
}
}
我已经在 class B 的定义中有一个 属性 A:
export default class B {
account;
constructor() {
this.account = new A();
}
}
连接这两者的 correct/standard 方法是什么,所以每次 class A 的套接字消息回调是,我都会从 class A 得到一个 'data' 对象触发了吗?
我对 JS
有点陌生,但在 iOS
上,我们会使用委托模式和协议,上面写着:
- class
A
将有一个代表 属性. - 委托 (class
B
) 必须实现协议(在这种情况下,需要实现名为didReceiveMessage(data)
的方法。 - 在那之后,当在 class
A
中收到消息时,我们将(在上面显示的套接字消息回调中)像 this.delegate.didReceiveMessage(data).
这里的协议使用一般来说并不重要,但它是一个加号,因为从 A
class,我们只能通过委托 属性 访问 didReceiveData(data)
方法,仅此而已( class B 的其他属性/方法不可见)。至少在 Swift/Obj-C
中是这样。我刚刚提到了它,因为我很好奇它在 JS 中也是如何完成的。
我想 Javascript
中有一些类似的机制,或者更多 standard/better 方法来实现这种对象之间的数据发送?
我不是 NodeJs 专家,但你可以使用类似 emitter plugin.
的东西在 javascript 中,它看起来像这样:
function A() {
Emitter(this);
this.action = function() {
console.log("something happened");
this.emit("action", { prop: "value" });
};
}
function B(a_instance) {
// subscribe to "action" event
a.on("action", function(data) {
console.log(data.prop); // "value"
});
};
var myA = new A();
var myB = new B(myA);
myA.action();
on iOS we would use a delegation pattern, with a protocol
你完全可以按照你描述的去做:
export default class A {
client;
delegate;
constructor(delegate) {
this.delegate = delegate;
this.client = new Spot(constants.apiKey, constants.apiSecret, {
baseURL: constants.baseURL,
wsURL: constants.wsURL,
});
const callbacks = {
open: () => this.client.logger.debug('open'),
close: () => this.client.logger.debug('closed'),
message: (data) => this.delegate.didReceiveMessage(data),
};
this.client.userData(listenKey, callbacks);
}
}
export default class B {
account;
constructor() {
this.account = new A(this);
}
didReceiveMessage(data) {
console.log(data); // or whatever
}
}
没有接口(协议)声明可以告诉 A
它可以在传递的 delegate
上访问哪些属性和方法,但合同当然存在。你应该用散文来记录它。 (或使用 TypeScript)。
另请注意您的 class A
如何与 Spot
客户端交互,它使用与事件处理程序方法传递对象非常相同的模式。
如果您的协议中只需要一个方法,JavaScript 中的一个更简单的模式就是只传递一个可调用函数:
export default class A {
client;
constructor(onMessage) {
this.client = new Spot(constants.apiKey, constants.apiSecret, {
baseURL: constants.baseURL,
wsURL: constants.wsURL,
});
this.client.userData(listenKey, {
open: () => this.client.logger.debug('open'),
close: () => this.client.logger.debug('closed'),
message: onMessage,
});
}
}
export default class B {
account;
constructor() {
this.account = new A(this.didReceiveMessage.bind(this));
// or inline:
this.account = new A(data => {
console.log(data); // or whatever
});
}
didReceiveMessage(data) {
console.log(data); // or whatever
}
}