我试图围绕回调和事件。每种都有两种常见的模式。哪一个被认为是最佳实践,为什么?
我有callback-oriented piece of code如下:
$(function() {
console.log('Document ready');
getData();
})
function getData(){
var url = "http://ip.jsontest.com/";
$.ajax({
dataType: "json",
url: url,
success: function(data){
buildElements(data, writeData)
}
});
}
function buildElements(data, callback) {
$('div.foo').append("<div class='bar'></div>");
callback(data);
}
function writeData(data){
$('div.bar').append('<p>Your IP is ' + data.ip + '</p>');
}
然后event-oriented piece of code(遵循观察者模式)如下:
$(function() {
console.log('Document ready');
getData();
})
function getData(){
var url = "http://ip.jsontest.com/";
$.ajax({
dataType: "json",
url: url,
success: function(data){
$('div.foo').trigger('getDataDone', data);
}
});
}
//build elements
$('div.foo').on('getDataDone', function(event, data) {
$('div.foo').append("<div class='bar'></div>")
$('div.foo').trigger('elementsBuilt', data);
})
//write data
$('div.foo').on('elementsBuilt', function(event, data) {
$('div.bar').append('<p>Your IP is ' + data.ip + '</p>');
})
答案 0 :(得分:1)
面向事件提供了更松散的耦合,因此它有好处,但同时更难跟踪系统的哪些部分进行通信,因此您可能不想开发一些工具来记录和检查哪些工具系统的组件发出事件并对事件做出反应。
您可能希望保留一些关于哪些组件可以附加事件处理程序的规则。我已经看到,最好不要在叶子组件中附加事件,并在父母那里调用事件来调用适当的孩子的方法。
你可能不想看看承诺。它比回调更松散,但同时它们明确地传递给你的代码,所以只需查看源代码就可以更容易地跟踪发生的事情。
承诺示例:
$(function() {
console.log('Document ready');
gettingData()
.done(function(data) {
buildingElements(data)
.done(writeData);
});
//// alternatively:
//gettingData()
//.then(buildingElements)
//.done(writeData);
})
function gettingData(){
var url = "http://ip.jsontest.com/";
// $.ajax returns a promise
return $.ajax({
dataType: "json",
url: url
});
}
function buildingElements(data) {
$('div.foo').append("<div class='bar'></div>");
// returns immediately resolved promise, but it could return a promise but resolve it asynchronously later
return $.Deferred().resolve(data).promise();
}
function writeData(data){
$('div.bar').append('<p>Your IP is ' + data.ip + '</p>');
}
答案 1 :(得分:1)
回调模式的某种程序性质允许您更严格地定义程序流程。逻辑将是:
等等。这对于ajax调用非常有效,因为执行路径很容易维护。
观察者模式可以允许多个侦听器对事件进行操作(他们正在观察更改)。所以它看起来像:
因此,在您的观察者示例中,您可以轻松地拥有更多.on('elementsBuilt')并且可以相对同时执行大量其他操作。非常适合观察者活跃并在完全随意的时间死亡。
就最佳实践而言,这取决于您要实现的目标。如果您需要更加定义的解决方案,而您通常希望一次只执行一个操作,请转到回调模式路径。如果您需要在不同的地方发生多件事情,并且您特别不关心谁先处理事件的顺序,请转到观察者模式路线。