I have a javascript function which needs to do a numerical calculation. Some of the numbers used in this calculation are stored in a database, and they will differ depending on how a user fills out an online form. Once the user fills out the form, they will click the CALCULATE button. At this time, in the JS function, I would like to use ajax to get values from a database that correspond to some other value chosen by the user.
我有一个需要进行数值计算的javascript函数。此计算中使用的某些数字存储在数据库中,它们将根据用户填写在线表单的方式而有所不同。一旦用户填写表单,他们将单击CALCULATE按钮。此时,在JS函数中,我想使用ajax从数据库中获取与用户选择的其他值相对应的值。
For a simple example: there are 3 sizes of t-shirts, with different prices based on each size (stored in database). The user chooses the size, and when they click CALCULATE, I use ajax to get the price associated with the size they chose.
举个简单的例子:有3种尺寸的T恤,每种尺码都有不同的价格(存储在数据库中)。用户选择大小,当他们点击CALCULATE时,我使用ajax来获得与他们选择的大小相关的价格。
The question is, i want to use ajax to update some variables that I will use later on in the script. The way I am trying to do it now doesn't work, the variable in the script doesn't get updated from ajax, I can only access the value from the database inside the success
function of the ajax call. I understand this is because ajax in asynchronous by nature, and it takes some time, waiting for the data to be returned from the server, while the function still continues to run
问题是,我想使用ajax更新一些我稍后将在脚本中使用的变量。我现在尝试这样做的方式不起作用,脚本中的变量没有从ajax更新,我只能从ajax调用的success函数内的数据库中访问值。我理解这是因为ajax本质上是异步的,并且需要一些时间,等待从服务器返回数据,而该函数仍然继续运行
In the following example, the ajax call returns JSON data, and I have a function called isjson()
that tests if the returned string is in fact JSON data.
在下面的示例中,ajax调用返回JSON数据,我有一个名为isjson()的函数,用于测试返回的字符串是否实际上是JSON数据。
Example code:
示例代码:
function calculate_cost(){
var price = 0;
var size = $('form#tshirt_form [name="size"] option:selected').val();
$.ajax({
url:'my_script.php',
type:'post',
data:'select=price&table=tshirts.prices&where=size = "' + size + '"',
success:function(data){
if(isjson(data)){
data = $.parseJSON(data);
data = data[0];
price = data['price'];
}else{
//display error getting data
}
}
});
// continue code for calculation
// this alert will display "0", but I want the price from the database in there
alert(price);
//perhaps do other ajax calls for other bits of data
//...
return final_price;
}
Does anyone know how I can accomplish this, updating variables with ajax in real-time??
有谁知道如何实现这一点,用ajax实时更新变量?
Thanks a lot!
非常感谢!
** EDIT **
**编辑**
Thanks everyone for the help, I understand about ajax being asynchronous. I would really like an answer where I don't have to continue the calculation inside the success
function, because my actual problem involves many values from quite a few different tables. I would also like to be able to expand on the calculation in the future without it getting too convoluted. If this is not possible, ever, than i will have to live with that. ;-)
感谢大家的帮助,我理解ajax是异步的。我真的想要一个答案,我不必在成功函数中继续计算,因为我的实际问题涉及来自不同表的许多值。我还希望将来可以扩展计算,而不会让它太复杂。如果这是不可能的,那么,我将不得不忍受这一点。 ;-)
** EDIT 2 **
**编辑2 **
OK, we got the answer: of course it is right near the top on the docs page, :-/ sorry about that. The async
property in jQuery ajax call. http://api.jquery.com/jQuery.ajax/
好的,我们得到了答案:当然它在文档页面的顶部附近,: - /抱歉。 jQuery ajax调用中的async属性。 http://api.jquery.com/jQuery.ajax/
6 个解决方案
#1
12
That is because ajax
executes the request asynchronously by default and before the control reaches alert(price);
the request has not yet executed and price
still holds the old value.
这是因为默认情况下ajax异步执行请求,然后控制达到警报(价格);请求尚未执行且价格仍保留旧值。
If you want to execute it synchronously then you can set async
to false.
如果要同步执行它,则可以将async设置为false。
$.ajax({
async: false,
.....
.....
});
#2
2
you need to calculate inside the success function
你需要在成功函数里面计算
function calculate_cost(){
var price = 0;
var size = $('form#tshirt_form [name="size"] option:selected').val();
$.ajax({
url:'my_script.php',
type:'post',
data:'query=select price from tshirts.prices where size = "' + size + '"',
success:function(data){
if(isjson(data)){
data = $.parseJSON(data);
data = data[0];
price = data['price'];
// continue code for calculation
// this alert will display "0", but I want the price from the database in there
alert(price);
//perhaps do other ajax calls for other bits of data
//...
}else{
//display error getting data
}
}
});
// return final_price; this function wont be able to return a value
}
#3
1
ajax is asynchronous and for this reason you should refactor your code so that you do what you need to do in the callback
ajax是异步的,因此您应该重构代码,以便在回调中执行您需要执行的操作
$.ajax({
url:'my_script.php',
type:'post',
data:'query=select price from tshirts.prices where size = "' + size + '"',
success:function(data){
if(isjson(data)){
data = $.parseJSON(data);
data = data[0];
price = data['price'];
//call another function (maybe make another ajax call) from here
dosomethingwithprice(price);
}else{
//display error getting data
}
}
});
#4
1
Your ajax code takes time to execute (albeit not much); however the code after the ajax call is executed asynchronously, and most likely before the results of the ajax call come in.
你的ajax代码需要时间来执行(尽管不多);但是,ajax调用之后的代码是异步执行的,并且很可能在ajax调用的结果进入之前。
Instead, why don't you try moving alert(price) into the body of the if(isjson(data))
region, and then execute a callback function which returns the price to whatever other utility you need it to be used at?
相反,为什么不尝试将警报(价格)移动到if(isjson(数据))区域的主体中,然后执行回调函数,该函数将价格返回到您需要使用的其他任何实用程序?
#5
1
you have to do your calculation inside callback stack. Ajax work async, that means that, codes outsides callback function run before callback function start. So you should do your calculation in callback.
你必须在回调堆栈中进行计算。 Ajax工作异步,这意味着,在回调函数启动之前,代码外部的回调函数运行。所以你应该在回调中进行计算。
function calculate_cost(){
var price = 0;
var size = $('form#tshirt_form [name="size"] option:selected').val();
$.ajax({
url:'my_script.php',
type:'post',
data:'query=select price from tshirts.prices where size = "' + size + '"',
success:function(data){
if(isjson(data)){
data = $.parseJSON(data);
data = data[0];
price = data['price'];
}else{
//display error getting data
}
// continue code for calculation
// this alert will display "0", but I want the price from the database in there
alert(price);
//perhaps do other ajax calls for other bits of data
//...
return final_price;
}
});
}
#6
0
I suggest having the ajax call return a deferred object. Then, when the final price is completely calculated, resolve the deferred object with that value.
我建议让ajax调用返回一个延迟对象。然后,在完全计算最终价格时,使用该值解析延迟对象。
function calculate_cost() {
var price = 0,
size = $('#tshirt_form [name="size"] option:selected').val(),
def = $.Deferred();
$.ajax({
data: {size:size},
url: 'my_script.php',
type: 'post',
dataType: 'json',
}).done(function(data){
data = data[0];
price = data['price'];
def.resolve(price);
}).fail(function(){
// do on error stuff
});
return def.promise();
}
// ...
calculate_cost("large").done(function(price){
alert(price);
}).fail(function(){
alert("Failed to retrieve price");
});
#1
12
That is because ajax
executes the request asynchronously by default and before the control reaches alert(price);
the request has not yet executed and price
still holds the old value.
这是因为默认情况下ajax异步执行请求,然后控制达到警报(价格);请求尚未执行且价格仍保留旧值。
If you want to execute it synchronously then you can set async
to false.
如果要同步执行它,则可以将async设置为false。
$.ajax({
async: false,
.....
.....
});
#2
2
you need to calculate inside the success function
你需要在成功函数里面计算
function calculate_cost(){
var price = 0;
var size = $('form#tshirt_form [name="size"] option:selected').val();
$.ajax({
url:'my_script.php',
type:'post',
data:'query=select price from tshirts.prices where size = "' + size + '"',
success:function(data){
if(isjson(data)){
data = $.parseJSON(data);
data = data[0];
price = data['price'];
// continue code for calculation
// this alert will display "0", but I want the price from the database in there
alert(price);
//perhaps do other ajax calls for other bits of data
//...
}else{
//display error getting data
}
}
});
// return final_price; this function wont be able to return a value
}
#3
1
ajax is asynchronous and for this reason you should refactor your code so that you do what you need to do in the callback
ajax是异步的,因此您应该重构代码,以便在回调中执行您需要执行的操作
$.ajax({
url:'my_script.php',
type:'post',
data:'query=select price from tshirts.prices where size = "' + size + '"',
success:function(data){
if(isjson(data)){
data = $.parseJSON(data);
data = data[0];
price = data['price'];
//call another function (maybe make another ajax call) from here
dosomethingwithprice(price);
}else{
//display error getting data
}
}
});
#4
1
Your ajax code takes time to execute (albeit not much); however the code after the ajax call is executed asynchronously, and most likely before the results of the ajax call come in.
你的ajax代码需要时间来执行(尽管不多);但是,ajax调用之后的代码是异步执行的,并且很可能在ajax调用的结果进入之前。
Instead, why don't you try moving alert(price) into the body of the if(isjson(data))
region, and then execute a callback function which returns the price to whatever other utility you need it to be used at?
相反,为什么不尝试将警报(价格)移动到if(isjson(数据))区域的主体中,然后执行回调函数,该函数将价格返回到您需要使用的其他任何实用程序?
#5
1
you have to do your calculation inside callback stack. Ajax work async, that means that, codes outsides callback function run before callback function start. So you should do your calculation in callback.
你必须在回调堆栈中进行计算。 Ajax工作异步,这意味着,在回调函数启动之前,代码外部的回调函数运行。所以你应该在回调中进行计算。
function calculate_cost(){
var price = 0;
var size = $('form#tshirt_form [name="size"] option:selected').val();
$.ajax({
url:'my_script.php',
type:'post',
data:'query=select price from tshirts.prices where size = "' + size + '"',
success:function(data){
if(isjson(data)){
data = $.parseJSON(data);
data = data[0];
price = data['price'];
}else{
//display error getting data
}
// continue code for calculation
// this alert will display "0", but I want the price from the database in there
alert(price);
//perhaps do other ajax calls for other bits of data
//...
return final_price;
}
});
}
#6
0
I suggest having the ajax call return a deferred object. Then, when the final price is completely calculated, resolve the deferred object with that value.
我建议让ajax调用返回一个延迟对象。然后,在完全计算最终价格时,使用该值解析延迟对象。
function calculate_cost() {
var price = 0,
size = $('#tshirt_form [name="size"] option:selected').val(),
def = $.Deferred();
$.ajax({
data: {size:size},
url: 'my_script.php',
type: 'post',
dataType: 'json',
}).done(function(data){
data = data[0];
price = data['price'];
def.resolve(price);
}).fail(function(){
// do on error stuff
});
return def.promise();
}
// ...
calculate_cost("large").done(function(price){
alert(price);
}).fail(function(){
alert("Failed to retrieve price");
});