这就是我所拥有的:
function loadGraphs(datawijk){
$.ajax({
url: './api5.php', //the script to call to get data
data: {
wijk: datawijk,
}, //you can insert url argumnets here to pass to api.php
//for example "id=5&parent=6"
dataType: 'json', //data format
success: function(rows) //on recieve of reply
{
var htmlContent = "";
// ADD TO
htmlContent += '<tr><th scope="row">Geboortes</th>';
$.each(rows, function(i, data) {
$.each(data, function(j, year) {
htmlContent +=
'<td>' + year + '</td>';
});
});
htmlContent += '</tr>';
var lol = updateOverlijdens(datawijk, htmlContent);
alert(lol);
$('#graphs table tbody').html(htmlContent);
}
});
}
function updateOverlijdens(datawijk, htmlContent){
$.ajax({
url: './api4.php', //the script to call to get data
data: {
wijk: datawijk,
}, //you can insert url argumnets here to pass to api.php
//for example "id=5&parent=6"
dataType: 'json', //data format
success: function(rows) //on recieve of reply
{
// ADD TO
htmlContent += '<tr><th scope="row">Overlijdens</th>';
$.each(rows, function(i, data) {
$.each(data, function(j, year) {
htmlContent +=
'<td>' + year + '</td>';
});
});
htmlContent += '</tr>';
return htmlContent;
}
});
}
当我发出警报时(笑);在函数loadGraphs我得到未定义... 当我做警报时(htmlContent);在函数updateOverlijdens中,在我返回值之前,我就把它弄好了。只有当我提醒我的函数loadGraphs中的值时,我才会被定义。我该如何解决这个问题?
答案 0 :(得分:4)
您未定义的原因是您没有从updateOverlijdens
返回任何内容(但是从内部函数中成功返回)
您正在运行异步代码,通常使用当前正在使用的函数返回模式无法轻松解决此问题,因为返回时数据将不可用。你需要的是回调。
有关jQuery ajax的良好用法示例,请参阅this page。您要做的是将函数传递给updateOverlijdens,并在您的ajax成功回调触发时调用它。网上有很多例子(在上面的链接中)。
这里的例子是你的代码被修改为正确的回调模式,解决了与异步执行有关的问题
function loadGraphs(datawijk){
$.ajax({
url: './api5.php', //the script to call to get data
data: {
wijk: datawijk,
}, //you can insert url argumnets here to pass to api.php
//for example "id=5&parent=6"
dataType: 'json', //data format
success: function(rows) //on recieve of reply
{
var htmlContent = "";
// ADD TO
htmlContent += '<tr><th scope="row">Geboortes</th>';
$.each(rows, function(i, data) {
$.each(data, function(j, year) {
htmlContent +=
'<td>' + year + '</td>';
});
});
htmlContent += '</tr>';
updateOverlijdens(datawijk, htmlContent,function(lol){
alert(lol);
$('#graphs table tbody').html(lol);
});
}
});
}
function updateOverlijdens(datawijk, htmlContent,callback){
$.ajax({
url: './api4.php', //the script to call to get data
data: {
wijk: datawijk,
}, //you can insert url argumnets here to pass to api.php
//for example "id=5&parent=6"
dataType: 'json', //data format
success: function(rows) //on recieve of reply
{
// ADD TO
htmlContent += '<tr><th scope="row">Overlijdens</th>';
$.each(rows, function(i, data) {
$.each(data, function(j, year) {
htmlContent +=
'<td>' + year + '</td>';
});
});
htmlContent += '</tr>';
callback(htmlContent)
}
});
}
答案 1 :(得分:1)
正如许多答案所解释的那样,问题在于您尝试将某些内容从AJAX调用返回到发起调用的函数。这不起作用,因为调用者不等待AJAX调用完成,并将在完成之前返回。关于异步调用的整个想法是:您不想阻止执行以等待结果进入。
处理此问题的一种方法是传递一个回调函数,该函数需要在检索结果时执行。然后将在AJAX成功回调中调用此函数。
另一个有趣的方法是使用jQuery的deferred和promise。承诺代表将来某处将被检索的某些价值。延迟产生一个承诺并在以后解决它。例如,所有AJAX函数都返回一个promise,您可以从任何jQuery对象中检索一个promise,该对象在完成所有动画后解析。
在您的情况下,您可以创建一个延迟,当检索到AJAX结果时,该延迟将使用htmlContent
解析。您返回从函数延迟的承诺,以便调用者可以将回调绑定到它或将其与其他承诺结合起来。
function updateOverlijdens(datawijk) {
// Create the deferred
var dfd = new jQuery.Deferred();
// Initiate the AJAX request
$.ajax({
url: './api4.php',
data: {
wijk: datawijk,
},
dataType: 'json',
success: function(rows) {
var htmlContent = '<tr><th scope="row">Overlijdens</th>';
$.each(rows, function(i, data) {
$.each(data, function(j, year) {
htmlContent += '<td>' + year + '</td>';
});
});
htmlContent += '</tr>';
// Resolve the deferred
dfd.resolve(htmlContent);
},
error: function() {
// An error occurred, reject the deferred
dfd.reject();
}
});
// Return a promise
return dfd.promise();
}
开始编辑
感谢Benjamin Gruenbaum指出我对deferred anti-pattern的使用。这是使用.then
进行链接的实现:
function updateOverlijdens(datawijk) {
return $.ajax({
url: './api4.php',
data: {
wijk: datawijk,
},
dataType: 'json'
}).then(function(rows) {
var htmlContent = '<tr><th scope="row">Overlijdens</th>';
$.each(rows, function(i, data) {
$.each(data, function(j, year) {
htmlContent += '<td>' + year + '</td>';
});
});
htmlContent += '</tr>';
return htmlContent;
});
}
结束编辑
然后您可以在loadGraphs
AJAX成功回调中使用承诺,如下所示:
// Produce the table header
var htmlContent = '<tr><th scope="row">Geboortes</th>';
$.each(rows, function(i, data) {
$.each(data, function(j, year) {
htmlContent += '<td>' + year + '</td>';
});
});
var promise = updateOverlijdens(datawijk);
promise.then(function(htmlOverlijdens) {
// Append to the previously created HTML content
htmlContent += htmlOverlijdens;
// Apply the HTML
$('#graphs table tbody').html(htmlContent);
});
使用promises的优势在于它们为调用者提供了更大的灵活性。调用者可以使用then()
轻松注册多个回调,使用jQuery.when()
将其与其他承诺结合使用,或使用 pipe()
then
将结果传递给另一个承诺
答案 2 :(得分:0)
是。没有错。您需要为$ .ajax定义的函数的返回值。在您的代码中,您将值返回到$ .ajax,而不是updateOverlijdens。正确的代码需要是:
function updateOverlijdens(datawijk, htmlContent){
$.ajax({ ....})
return 'some value'
}