Javascript 寻找链接AJAX调用的模式
我们有一个AJAX web应用程序,我们有一个常见的模式,就是一个接一个地调用多个AJAX调用。这在保存带有多个附加实体的内容时很常见。例如,saveCustomer()-->saveCustomerAddress()-->saveCustomerOrder() 我们目前拥有它,因此当methodA()成功时,即第一个方法,它调用methodB(),以此类推(见下面的代码)。这种模式的缺点是很难看到发生了什么。如果您阅读了methodA(),您从阅读方法名称中不知道它也调用了methodB()和methodC()。另一个缺点是,如果你想改变链接,你必须重写大量的代码,如果你只想单独调用一个方法,这是无法做到的,因为它会调用下游的方法Javascript 寻找链接AJAX调用的模式,javascript,ajax,design-patterns,Javascript,Ajax,Design Patterns,我们有一个AJAX web应用程序,我们有一个常见的模式,就是一个接一个地调用多个AJAX调用。这在保存带有多个附加实体的内容时很常见。例如,saveCustomer()-->saveCustomerAddress()-->saveCustomerOrder() 我们目前拥有它,因此当methodA()成功时,即第一个方法,它调用methodB(),以此类推(见下面的代码)。这种模式的缺点是很难看到发生了什么。如果您阅读了methodA(),您从阅读方法名称中不知道它也调用了methodB()和
function Tester() {
this.url = 'https://public.opencpu.org/ocpu/library/';
this.save = function() {
this.methodA();
}
this.methodA = function () {
var self = this;
$.ajax({
url: self.url,
async: true
}).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
//check for errors... and if OK
alert('A OK');
self.methodB();
})
}
this.methodB = function () {
var self = this;
$.ajax({
url: self.url,
async: true
}).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
//check for errors... and if OK
alert('B OK');
self.methodC();
})
}
this.methodC = function () {
var self = this;
$.ajax({
url: self.url,
async: true
}).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
//OK
alert('C OK');
})
}
}
new Tester().save();
我挠头想找出一个更好的模式。我想您可以将后面的方法封装在回调函数中,然后以某种方式将它们传递给每个方法,但我不确定如何实现这一点
是否有人知道在链接方法时可以删除方法依赖项的常见模式类型?尝试以下方法:
function Tester() {
var self = this;
this.url = 'https://public.opencpu.org/ocpu/library/';
this.save = function() {
self.methodA().then( self.methodB() ).then( self.methodC() )
}
this.methodA = function () {
var self = this;
return $.ajax({
url: self.url,
async: true
}).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
//check for errors... and if OK
alert('A OK');
})
}
this.methodB = function () {
var self = this;
return $.ajax({
url: self.url,
async: true
}).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
//check for errors... and if OK
alert('B OK');
})
}
this.methodC = function () {
var self = this;
return $.ajax({
url: self.url,
async: true
}).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
//OK
})
}
}
new Tester().save();
试试这个:
function Tester() {
var self = this;
this.url = 'https://public.opencpu.org/ocpu/library/';
this.save = function() {
self.methodA().then( self.methodB() ).then( self.methodC() )
}
this.methodA = function () {
var self = this;
return $.ajax({
url: self.url,
async: true
}).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
//check for errors... and if OK
alert('A OK');
})
}
this.methodB = function () {
var self = this;
return $.ajax({
url: self.url,
async: true
}).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
//check for errors... and if OK
alert('B OK');
})
}
this.methodC = function () {
var self = this;
return $.ajax({
url: self.url,
async: true
}).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
//OK
})
}
}
new Tester().save();
函数A(){
writeMessage(“调用函数A”);
返回$.ajax({
url:“/scripts/S9/1.json”,
键入:“获取”,
数据类型:“json”
});
}
函数B(结果罗马){
writeMessage(“在函数B中。A的结果=“+ResultFrom A.data”);
返回$.ajax({
url:“/scripts/S9/2.json”,
键入:“获取”,
数据类型:“json”
});
}
函数C(resultFromB){
writeMessage(“在函数C中,B的结果=“+resultFromB.data”);
返回$.ajax({
url:“/scripts/S9/3.json”,
键入:“获取”,
数据类型:“json”
});
}
函数D(resultFromC){
writeMessage(“在函数D中,C的结果=“+ResultFrom C.data”);
}
然后(B)然后(C)然后(D);
函数writeMessage(msg){
$(“#段”)。追加(msg+””;
}
函数A(){
writeMessage(“调用函数A”);
返回$.ajax({
url:“/scripts/S9/1.json”,
键入:“获取”,
数据类型:“json”
});
}
函数B(结果罗马){
writeMessage(“在函数B中。A的结果=“+ResultFrom A.data”);
返回$.ajax({
url:“/scripts/S9/2.json”,
键入:“获取”,
数据类型:“json”
});
}
函数C(resultFromB){
writeMessage(“在函数C中,B的结果=“+resultFromB.data”);
返回$.ajax({
url:“/scripts/S9/3.json”,
键入:“获取”,
数据类型:“json”
});
}
函数D(resultFromC){
writeMessage(“在函数D中,C的结果=“+ResultFrom C.data”);
}
然后(B)然后(C)然后(D);
函数writeMessage(msg){
$(“#段”)。追加(msg+””;
}
您可以像这样使用动态调用:
this.reqChain = ['req_1', 'req_2'];
this.callChain = function(){
if(!self.reqChain.length) return;
ajax({
url: self.reqChain[0],
async: true,
always: function(processedDataOrXHRWrapper, textStatus, whrWrapperOrErrorThrown){
self.reqChain.shift();
$(document).trigger('request_'+self.reqChain[0]+'_callback', [processedDataOrXHRWrapper, textStatus, whrWrapperOrErrorThrown])
self.callChain();
}
});
}
您可以传递回调,也可以绑定到动态事件。您可以像这样使用动态调用:
this.reqChain = ['req_1', 'req_2'];
this.callChain = function(){
if(!self.reqChain.length) return;
ajax({
url: self.reqChain[0],
async: true,
always: function(processedDataOrXHRWrapper, textStatus, whrWrapperOrErrorThrown){
self.reqChain.shift();
$(document).trigger('request_'+self.reqChain[0]+'_callback', [processedDataOrXHRWrapper, textStatus, whrWrapperOrErrorThrown])
self.callChain();
}
});
}
您可以传递回调,也可以绑定到动态事件。以下是我对自己问题的回答。我将所有方法包装在函数中,并通过回调传递到方法中 它似乎能完成任务。有人有什么意见吗
function Tester2() {
this.save = function() {
var self = this;
var callbackC = function() {
self.methodC();
}
var callbackB = function() {
self.methodB(callbackC);
}
this.methodA(callbackB);
}
this.methodA = function (callbackFn) {
var self = this;
$.ajax({
url: self.url,
async: true
}).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
//check for errors... and if OK
alert('A OK');
if (callbackFn)
callbackFn();
})
}
this.methodB = function (callbackFn) {
var self = this;
$.ajax({
url: self.url,
async: true
}).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
//check for errors... and if OK
alert('B OK');
if (callbackFn)
callbackFn();
})
}
this.methodC = function () {
var self = this;
$.ajax({
url: self.url,
async: true
}).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
//OK
alert('C OK');
})
}
}
new Tester2().save();
这是我对自己问题的回答。我将所有方法包装在函数中,并通过回调传递到方法中 它似乎能完成任务。有人有什么意见吗
function Tester2() {
this.save = function() {
var self = this;
var callbackC = function() {
self.methodC();
}
var callbackB = function() {
self.methodB(callbackC);
}
this.methodA(callbackB);
}
this.methodA = function (callbackFn) {
var self = this;
$.ajax({
url: self.url,
async: true
}).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
//check for errors... and if OK
alert('A OK');
if (callbackFn)
callbackFn();
})
}
this.methodB = function (callbackFn) {
var self = this;
$.ajax({
url: self.url,
async: true
}).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
//check for errors... and if OK
alert('B OK');
if (callbackFn)
callbackFn();
})
}
this.methodC = function () {
var self = this;
$.ajax({
url: self.url,
async: true
}).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
//OK
alert('C OK');
})
}
}
new Tester2().save();
使用承诺。jQuery拥有它,或者任何其他库。看看这里:或者这里,或者,不太高级的,只使用回调…使用承诺。jQuery拥有它,或者任何其他库。看看这里:或者这里,或者,不太高级的,只使用回调……来详细说明:这是使用承诺,它内置于jQuery的Ajax实现中。更多信息可以在jQuery文档中找到,但它使用的是错误的。您需要将回调传递给
。然后()!我不知道为什么有人投你反对票。这似乎很好用。不,不行。它并行执行所有三个ajax请求,与您希望的顺序执行相反。在他的例子中,他正在执行这个方法。。。ie在传递到then()方法时使用(),而在另一个答案中,只传递方法引用:这是使用承诺,它内置于jQuery的Ajax实现中。更多信息可以在jQuery文档中找到,但它使用的是错误的。您需要将回调传递给。然后()!我不知道为什么有人投你反对票。这似乎很好用。不,不行。它并行执行所有三个ajax请求,与您希望的顺序执行相反。在他的例子中,他正在执行这个方法。。。ie在传递到then()方法时使用(),而在另一个答案中,只有方法引用被传递到phewho中,这与另一个答案有什么不同?您刚刚从ajax调用返回,对吗?那么这会阻止它异步吗?jQuery Doc:Callbacks是按添加顺序执行的。因为deferred.then返回一个承诺,所以Promise对象的其他方法可以链接到此方法,包括其他.then()方法。这就是我们在这里所做的。jQuery的每个Ajax方法都已经返回了一个承诺。当函数A中的Ajax调用完成时,它将解析承诺。然后调用函数B(),将Ajax调用的结果作为其第一个参数。当B()中的ajax调用完成时,它将解析承诺,并使用该调用的结果调用函数C(),依此类推。我修改了我的代码以适应他的解决方案:这与另一个答案有何不同?您刚刚从ajax调用返回,对吗?那么这会阻止它吗