我们有一个AJAX Web应用程序,我们拥有的一个常见模式是一个接一个调用的ajax调用。当我们使用多个附加实体保存某些内容时,这很常见。示例可能是 saveCustomer() - > saveCustomerAddress() - >的 saveCustomersOrder()
我们目前拥有它,以便当 methodA()成功时,即第一种方法,它会调用 methodB(),等等(请参阅下面的代码)。这种模式的缺点是很难看到发生了什么。如果您阅读 methodA(),则无法通过阅读方法名称来调用 methodB()和 methodC()。另一个缺点是,如果你想改变链接,你必须重写大量的代码,如果你只想单独调用一个方法,那么它就无法完成,因为它会调用下游的方法。
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();
我正在试图找出一个更好的模式。我想你可以在回调函数中包含后面的方法,然后以某种方式将它们传递给每个方法,但我不确定如何处理它。
是否有人知道一种常见的模式类型,您可以在链接方法时删除方法依赖项?
答案 0 :(得分:3)
function A() {
writeMessage("Calling Function A");
return $.ajax({
url: "/scripts/S9/1.json",
type: "GET",
dataType: "json"
});
}
function B(resultFromA) {
writeMessage("In Function B. Result From A = " + resultFromA.data);
return $.ajax({
url: "/scripts/S9/2.json",
type: "GET",
dataType: "json"
});
}
function C(resultFromB) {
writeMessage("In Function C. Result From B = " + resultFromB.data);
return $.ajax({
url: "/scripts/S9/3.json",
type: "GET",
dataType: "json"
});
}
function D(resultFromC) {
writeMessage("In Function D. Result From C = " + resultFromC.data);
}
A().then(B).then(C).then(D);
function writeMessage(msg) {
$("#para").append(msg + "</br>");
}
答案 1 :(得分:1)
您可以像这样使用动态调用:
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();
}
});
}
您可以传递回调,也可以绑定到动态事件。
答案 2 :(得分:1)
这是我对自己问题的回答。我将所有方法包装在函数中,并将回调传递给我的方法。
似乎做了这个工作。有没有人有任何意见?
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();
答案 3 :(得分:0)
试试这个:
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();