我有一个网页,它们之间连接着不同的元素(链接列表和两个选择框(。单击它们可能会影响另一个元素中的一个,并且它们的所有值都会影响更新要显示在页面上的值。
所以,代码是这样的:
$(document).ready(function() {
var someVar = '';
$("select#size").bind('change', function() {
someVar = $(this).val();
console.log('first');
});
my_change();
console.log('second' + someVar);
});
function my_change() {
$.getJSON("photos/change_product", {json_stuff}, function(data) {
var options = [];
for (var i = 0; i < data.length; i++) {
options.push('<option value="' + data[i].id + '">' + data[i].label + '</option>');
}
$("select#size").trigger('change');
$("select#options").html(options.join('')).trigger('change');
})
};
};
当我加载页面时,会调用my_change
函数。它做一些事情,然后在选择框上触发change event
。我需要使用这个选择框中的内容来更新一个值,然后才能继续执行。所以我需要这个代码做的是打印变量值的"first",然后打印"second"。实际情况是,它打印的是"第二个"第一个"。
我想这是因为我正在进行异步调用。我能做什么?
有几种方法可以做到这一点。
您可以使用jQuery$when,并在ajax响应完成后调用console.log。
$(document).ready(function() {
var someVar = '';
$("select#size").bind('change', function() {
someVar = $(this).val();
console.log('first');
});
$.when( my_change() ).then(function(){
console.log('second' + someVar);
});
});
function my_change() {
return $.getJSON("photos/change_product", {json_stuff}, function(data) {
var options = [];
for (var i = 0; i < data.length; i++) {
options.push('<option value="' + data[i].id + '">' + data[i].label + '</option>');
}
$("select#size").trigger('change');
$("select#options").html(options.join('')).trigger('change');
})
};
};
或者,您可以向my_change(callback)
函数添加一个回调参数。
$(document).ready(function() {
var someVar = '';
$("select#size").bind('change', function() {
someVar = $(this).val();
console.log('first');
});
my_change(function(){ console.log('second' + someVar) } );
});
function my_change(callback) {
return $.getJSON("photos/change_product", {json_stuff}, function(data) {
var options = [];
for (var i = 0; i < data.length; i++) {
options.push('<option value="' + data[i].id + '">' + data[i].label + '</option>');
}
$("select#size").trigger('change');
if( typeof callback !== 'undefined' && typeof callback === 'function' )
callback();
$("select#options").html(options.join('')).trigger('change');
})
};
};
由于异步$.getJSON()
调用在启动其回调函数之前等待来自服务器的响应,因此首先调用"second"console.log()
。您可以将jqXHR对象保存到一个变量中,然后使用该变量运行带有$.when()
:的"第二个"consone.log()
$(function() {
var someVar = '';
$("#size").on('change', function() {//on() is the same as bind() here
someVar = $(this).val();
console.log('first');
});
//save the jQuery XHR object from your $.getJSON request
var jqXHR = my_change();
//when the above jQuery XHR object resolves, it will fire the second console.log
$.when(jqXHR).then(function () {
console.log('second' + someVar);
});
});
function my_change() {
//here we return the jQuery XHR object for the $.getJSON request so we can run code once it resolves
return $.getJSON("photos/change_product", {json_stuff}, function(data) {
var options = [];
for (var i = 0; i < data.length; i++) {
options.push('<option value="' + data[i].id + '">' + data[i].label + '</option>');
}
$("#size").trigger('change');
$("#options").html(options.join('')).trigger('change');
})
};
以下是$.when()
的文档:http://api.jquery.com/jquery.when
简要说明:向选择器添加标记类型通常较慢,尤其是在选择ID时,因为这已经是一种非常快速的选择元素的方法。
任何依赖于getJSON
响应的代码都必须放在getJSON
回调中或从中调用。
这就是回调的作用。
您应该注意,my_change
函数将无法访问someVar
变量,因为它是ready()
回调的本地变量。
要解决此问题,请在ready()
回调中移动my_change
函数。
或者直接将函数传递给my_change
。
my_change(function() {
console.log('second' + someVar);
});
并让getJSON
回调调用该函数。
function my_change( func ) {
$.getJSON("photos/change_product", {json_stuff}, function(data) {
var options = [];
for (var i = 0; i < data.length; i++) {
options.push('<option value="' + data[i].id + '">' + data[i].label + '</option>');
}
$("select#size").trigger('change');
$("select#options").html(options.join('')).trigger('change');
func();
});
}