【发布时间】:2013-07-02 03:32:44
【问题描述】:
以下函数的目的是访问雅虎服务器上的脚本并查找实时货币兑换率,该汇率稍后将用于处理客户的购买。
我能够访问 JavaScript 警报中的费率,但我似乎无法将它们返回到最初调用 getRate() 函数的 Jquery 方法。
我在parseExchangeRate() 函数的末尾尝试了一个标准的return rate;,但它不起作用。我也尝试将rate 设置为parseExchangeRate() 中的全局变量,但这也不起作用。
function getRate(from, to) {
var script = document.createElement('script');
script.setAttribute('src', "http://query.yahooapis.com/v1/public/yql?q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes%3Fs%3D"+from+to+"%253DX%26f%3Dl1n'%20and%20columns%3D'rate%2Cname'&format=json&callback=parseExchangeRate");
document.body.appendChild(script);
}
function parseExchangeRate(data) {
var name = data.query.results.row.name;
rate = parseFloat(data.query.results.row.rate, 10);
alert("Exchange rate " + name + " is " + rate);
}
$(function() {
getRate('USD', 'PHP');
xRatePHP = rate;
/* Do stuff with rate */
});
当我尝试在 Jquery 函数中访问它时,Firebug 告诉我 rate 未定义。
我尝试的另一件事是将http请求的最后一个参数设置为callback=rate=parseExchangeRate,这(不足为奇)也不起作用。
更新
@Relfor 解决了最初的问题,即 rate 没有正确声明为全局范围内的全局变量。我解决了这个问题,然后发现了另一个问题,有些人也在下面发现了这个问题,即在调用 getRate() 之后(更新变量 rate 可能需要大约 2000 毫秒),脚本立即继续运行,而无需等待 @987654333 @ 将被更新并使用费率,无论它是否准备好。
我尝试使用window.setInterval 来创建延迟来解决这个问题,当我注意到即使我已经接受了@Relfor 的回答,他们仍然在线程中活动,所以我更喜欢把它带回来,这样当我们开始工作时,其他人可以从解决方案中受益。
有一个最终(我希望 - 最终!) 问题,那就是为了简化发布的原始问题,我没有透露我实际上试图从雅虎! (可能还有更多计划),因此,我在循环中调用getRate(),如下所示:
function getRate(from, to) {
var script = document.createElement('script');
script.setAttribute('src', "http://query.yahooapis.com/v1/public/yql?q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes%3Fs%3D"+from+to+"%253DX%26f%3Dl1n'%20and%20columns%3D'rate%2Cname'&format=json&callback=parseExchangeRate");
document.body.appendChild(script);
}
function parseExchangeRate(data) {
var name = data.query.results.row.name;
rate = parseFloat(data.query.results.row.rate, 10);
}
var rate = 1.00;
var timer;
var q;
var xRatePHP, xRateGBP;
$(function() {
function getTheRates() {
var rateArr = new Array('PHP','GBP');
for (var x=0; x < rateArr.length; x++) {
getRate('USD', rateArr[x]);
q = 0;
timer = window.setInterval(function(){manageTimer(rateArr[x])},100);
}
}
function manageTimer(c) {
if (rate != 1) {
window.clearInterval(timer);
/* Note that 'c' is undefined according to 'alert' below,
* so this next line is not working correctly.
*/
eval("xRate"+c+" = rate;");
alert(c + " = " + rate); // displays 'undefined 43.543'
rate = 1.00;
}
q++;
if (q > 30 ) {
window.clearInterval(timer);
// added below because above isn't working (but neither does this!)
timer = '';
alert(c+' timeout'); // 'c' is undefined according to alert ???
q = 0;
}
}
getTheRates();
/* Do stuff with the rates */
});
有人建议我将/* Do stuff with the rates */ 移动到函数parseExchangeRate() 内部,但不确定该建议是否仍然有效,因为我透露了有关在循环中调用getRate() 的信息?
更新 3(替换更新 2)
我在这里创建了一个 JSbin:http://jsbin.com/udikas/3/edit,除了这两个问题之外,它似乎正在工作:
1) 超时机制似乎不起作用。
2) 在第 33 行这一行 alert('start timer (' + x +')'); 没有它,计时器似乎没有启动!我不知道为什么,但我不能把那条线留在里面。
【问题讨论】:
-
在使用之前不要给它赋值。由于这是一个非局部变量,它应该是一个 ReferenceError。但是,似乎缺少上下文,并且
parseExchangeRate可能是 AJAX 调用的回调。在这种情况下,请记住这一点:回调可能异步发生。 -
放弃 URL 的“回调”参数并简单地使用 AJAX 请求会不会更好,该请求会返回 JSON,然后您可以将其传递给您需要的任何函数。
-
@Paul 我在使用
rate之前没有赋值,但我现在只是尝试过,没有任何区别。这其中不涉及 AJAX。 -
@mibbler AJAX 是否可以跨域工作?我不认为它会。
-
我需要在调用函数之前在 Jquery 方法中初始化全局变量,而不是从内部初始化,这是我尝试过的。 @Paul 你是对的,但我需要下面 Relfor 的帮助来弄清楚该放在哪里。
标签: javascript jquery callback return jsonp