我创建了一个小的fetch函数,基本上只为我做了一个ajax POST
以及为了简洁我已删除的其他一些东西。在这个函数中,我传递一个回调函数,该函数应该在成功回调被触发时触发。
function ajax_fetch(url, fetch, data, callback) {
$.ajax({
type: "Post",
url: baseurl + url,
data: data,
contentType: "application/json",
dataType: "html",
success: function (response) {
fetch.html(response);
// if there's a callback, run it.
if (typeof callback == "function")
callback();
},
error: function (xhr, ajaxOptions, thrownError) {
handleErrors(xhr, ajaxOptions, thrownError);
}
});
}
下面我有一段代码,我基本上在做2个ajax调用。第一个触发正常的ajax POST
,然后成功后调用上面的ajax_fetch()
函数,所有函数都按预期工作。
$("#markstatus").singleBind("click", function () {
var step = "{ step : " + $(this).data("step") + "}";
$.ajax({
type: "POST",
url: baseurl + "SetStatus",
data: step,
contentType: "application/json",
dataType: "html",
success: function (result) {
$("#header.container").html(result);
ajax_fetch("/StepIndex", $(".replaceable"), step,
function() {
window.alerts.success("Step Complete");
});
},
error: function (xhr, ajaxOptions, thrownError) {
handleErrors(xhr, ajaxOptions, thrownError);
}
});
});
然而问题是:
$("#removestatus").singleBind("click", function () {
var step = "{ step : " + $(this).data("step") + "}";
ajax_fetch("RemoveStatus", $("#header.container"), step,
ajax_fetch("/StepIndex", $(".replaceable"), step,
function () {
window.alerts.warning("Step Re-Opened");
})
);
});
我认为我可能很棘手并且最初通过使用我的ajax_fetch()
函数进行基本上相同的双ajax调用,然后在另一个ajax_fetch()
中点击第一个回调传递时,所有应该是好的和花花公子。
但是当我查看我的控制台输出时:
customSpa.js:793 Object {url: "/StepIndex", fetch: jQuery.fn.init[1], data: "{ step : 1}", callbackl: function}
customSpa.js:801 requesting: /async//StepIndex
customSpa.js:793 Object {url: "RemoveStatus", fetch: jQuery.fn.init[1], data: "{ step : 1}", callbackl: undefined}
customSpa.js:801 requesting: /async/RemoveStatus
我可以看到它首先调用内部提取,然后是外部调用。这是一个异步/承诺类型的问题,或者我究竟做错了什么?
答案 0 :(得分:4)
您正在尝试将函数作为回调传递(稍后调用),但是您传递立即调用函数的结果。
你需要写这样的电话:
ajax_fetch("RemoveStatus", $("#header.container"), step,
function() {
ajax_fetch("/StepIndex", $(".replaceable"), step,
function () {
window.alerts.warning("Step Re-Opened");
})
}
);
......这应该不足为奇。内部回调是一个函数;外部回调也必须是一个函数。
答案 1 :(得分:1)
当您致电ajax_fetch
时,它正在执行ajax调用。您没有将该函数作为回调传递,您在此处调用该函数:
ajax_fetch("RemoveStatus", $("#header.container"), step,
ajax_fetch("/StepIndex", $(".replaceable"), step, // this makes the call
function () {
window.alerts.warning("Step Re-Opened");
})
);
答案 2 :(得分:1)
我建议使用jQuery的Promise功能而不是深度嵌套。
因此,您将从jqXHR
函数返回$.ajax
来自ajax_fetch
的{{1}}来电。在实现Promise界面时,您可以在其上调用.then
,在then
- 回调中,您可以进行下一次ajax_fetch
调用并返回jqXHR
。
function ajax_fetch(url, fetch, data) {
return $.ajax({
type: "Post",
url: baseurl + url,
data: data,
contentType: "application/json",
dataType: "html",
success: function (response) {
fetch.html(response);
},
error: function (xhr, ajaxOptions, thrownError) {
handleErrors(xhr, ajaxOptions, thrownError);
}
});
}
$("#removestatus").singleBind("click", function () {
var step = "{ step : " + $(this).data("step") + "}";
ajax_fetch("RemoveStatus", $("#header.container"), step)
.then(function() {
return ajax_fetch("/StepIndex", $(".replaceable"), step);
})
.then(function() {
window.alerts.warning("Step Re-Opened");
});
});
答案 3 :(得分:1)
正如其他人所说,你得到错误的原因是ajax_fetch(..., ..., ..., function () {...})
是函数调用,而不是函数。
此外,您正在做一些使代码不必要复杂的事情。
fetch
和callback
传递给ajax_fetch()。通过从函数返回$ .ajax(...)生成的jqXHR对象,任何调用函数都可以处理链式.then()
中的响应,并且还处理链末尾的错误条件。step
不需要是手工编码的JSON字符串。它可以写为对象文字,结果对象直接用作ajax .data
属性。因此,contentType: "application/json",
可以消失。你最终应该:
function ajax_fetch(url, data) {
return $.ajax({
^^^^^^
type: "POST",
url: baseurl + url,
data: data,
dataType: "html"
});
}
两个调用函数如下:
$("#markstatus").singleBind('click', function () {
var step = { step: $(this).data('step') };
ajax_fetch("SetStatus", step).then(function (result) {
$("#header.container").html(result);
return ajax_fetch("/StepIndex", step).then(function(response) {
$(".replaceable").html(response);
});
}).then(function() {
window.alerts.success("Step Complete");
}, handleErrors);
});
$("#removestatus").singleBind('click', function () {
var step = { step: $(this).data('step') };
ajax_fetch('RemoveStatus', step).then(function(result) {
$("#header.container").html(result);
return ajax_fetch("/StepIndex", step).then(function (response) {
$(".replaceable").html(response);
});
}).then(function() {
window.alerts.warning("Step Re-Opened");
}, handleErrors);
});
两个事件处理程序非常相似,您可以将它们组合在一起。您只需要一种机制来管理差异,即:
url
首先,为每个可点击元素设置一些数据。
$("#markstatus").data('params', {
'path':'SetStatus',
'message':'Step Complete'
});
$("#removestatus").data('params', {
'path':'RemoveStatus',
'message':'Step Re-Opened'
});
然后将单击处理程序附加到两个元素。
$("#markstatus, #removestatus").singleBind('click', function () {
var $this = $(this),
step = { 'step': $this.data('step') },
params = $this.data('params');
ajax_fetch(params.path, step).then(function(result) {
$("#header.container").html(result);
return ajax_fetch("/StepIndex", step).then(function (response) {
$(".replaceable").html(response);
});
}).then(function() {
window.alerts.warning(params.message);
}, handleErrors);
});