如何让此 JSONP 调用返回值
How can I get this JSONP call to return a value?
以下函数的目的是访问雅虎服务器上的脚本并查找实时货币兑换率,该汇率稍后将用于处理客户的购买。
我能够访问 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 */
});
Firebug 通知我,当我尝试在 Jquery 函数中访问它时,rate
是未定义的。
我尝试的另一件事是将 http 请求的最后一个参数设置为 callback=rate=parseExchangeRate
这也不起作用(毫不奇怪(。
更新
@Relfor解决了最初的问题,即rate
未在全局范围内正确声明为全局变量。我修复了这个问题,然后发现了一个进一步的问题,有些人也在下面发现了这个问题,那就是在调用getRate()
后(更新变量rate
可能需要大约 2000 毫秒(,脚本立即继续,无需等待rate
更新并使用速率,无论它是否准备就绪。
我尝试尝试使用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 +')');
没有它,计时器似乎不会启动!我不知道为什么,但我不能把那条线留在里面。
rate
尚未定义
$(function() {
getRate('USD', 'PHP');
xRatePHP = rate;
/* Do stuff with rate */
});
在研究了您的代码后,似乎 parseExchange(data)
函数中的 rate 定义为
function parseExchangeRate(data) {
var name = data.query.results.row.name;
rate = parseFloat(data.query.results.row.rate, 10);
alert("Exchange rate " + name + " is " + rate);
}
如果您希望从函数命名空间访问 rate,而无需从内部声明它们,则必须在任何函数或循环之外的全局命名空间中指定 rate。
编辑:命名空间问题已解决,我给出的答案已被接受,但是我想添加有关您在此处处理的代码的详细信息。它取自这里的要点:https://gist.github.com/henrik/265014
我们在这里处理 JSONP
乍一看,parseExchangeRate
存在的原因及其上下文似乎很神秘,尽管它的存在是 JSONP 请求与响应返回的数据之间的主要联系。
如果您仔细查看请求:
http://query.yahooapis.com/v1/public/yql?
q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2F
download.finance.yahoo.com%2Fd%2F
quotes%3Fs%3DUSDPHP%253DX%26f%3Dl1n'%20and%20
columns%3D'rate%2Cname'&format=json&callback=parseExchangeRate
(我将链接分成许多行以使其更易于阅读(
仔细查看网址的最后一段:callback=parseExchangeRate
这是连接,当JSONP请求完成解析时,将调用ExchangeRate。
那么为什么它不起作用呢?
让我再次显示代码:
$(function() {
getRate('USD', 'PHP');
xRatePHP = rate;
/* Do stuff with rate */
});
我们应该分解一下:
-
getRate('USD', 'PHP')
使用各自的货币类型"USD"和"PHP"加载 JSONP -
xRatePHP = rate
将rate
的右侧分配给xRatePHP
。但是这条线给我们带来了一个问题! 我们的控制台朋友告诉我们,rate
是不确定的!
真相:控制台先生没有撒谎,rate
实际上是未定义的,但是控制台先生没有给出任何进一步的命令,几分钟后,如果再次被问到,我会回答rate
实际上是定义的。这是魔法吗?
实际发生的事情是,在你从这条线出发的时间之间
getRate('USD', 'PHP');
自
xRatePHP = rate;
雅虎先生的JSONP回应还没有回来,这就是为什么当xRatePHP = rate
发布时rate
似乎没有定义。
硬代码解决方案
让我们硬编码代码,让我们的代码在使用rate
之前等待的持续时间,以便我们知道 mr.yahoo 做出了回应,setTimeout
will 在这里帮助我们:
getRate('USD', 'PHP');
setTimeout(function(){alert(rate)}, 2000);
现在一切正常! 查看演示: http://jsbin.com/udikas/1/edit
软代码
你有没有考虑过雅虎先生需要超过2000毫秒才能回复的情况?或者甚至可能比这更少?(雅虎非常快!让我们采用不同的方法,这将让我们使用rate
计算它的确切时刻parseExchangeRate
为此,我们必须添加一个来自parseExchangeRate
的回调:
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 parseExchangeRate(data) {
var name = data.query.results.row.name;
rate = parseFloat(data.query.results.row.rate, 10);
alert("Exchange rate " + name + " is " + rate);
gotTheRate(rate)
}
然后更改
$(function() {
getRate('USD', 'PHP');
alert(rate)
});
自
function gotTheRate(rate){
alert(rate);
}
$(function() {
getRate('USD', 'PHP');
});
有关此演示,请访问 http://jsbin.com/udikas/2/edit
多个回调(响应问题更新(
请记住,硬编码setTimeouts
并不有趣,所以让我们从您的代码中删除它,manageTimer
、q
和其他此类元素,相反,我们可以拥有:
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;
rateDict[name.match(/USD to (['w]*)/)[1]] = parseFloat(data.query.results.row.rate, 10);
total_responses++;
if (total_responses === rateArr.length){
for (var k in rateDict){
alert("USD to " + k + " is " + rateDict[k]);
}
}
}
var rate = 1.00;
var timer;
var q;
var rateArr = new Array('PHP','GBP')
var total_responses = 0;
var rateDict = {};
$(function() {
function getTheRates() {
for (var x=0; x < rateArr.length; x++) {
getRate('USD', rateArr[x]);
}
}
getTheRates();
});
http://jsbin.com/udikas/4/edit
-瑞福
您应该重新排序代码流:
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;
var rate = parseFloat(data.query.results.row.rate, 10);
alert("Exchange rate " + name + " is " + rate);
xRatePHP = rate;
/* Do stuff with rate */
}
$(function() {
getRate('USD', 'PHP');
// rate is not yet available here, so don't do anything with it
});
尝试输入:
var rate = 0;
在您的代码之上。这将修复错误。然后你必须考虑到,如果你得到0,也许你在错误的时间读取变量,在它被填充之前。
- 如何记录调用另一个函数的函数的返回值
- 单击按钮时,使用Javascript调用并返回值
- 从JSP页面调用Java Script函数未返回值
- jQuery 延迟的 AJAX 调用返回值
- 未使用返回值时调用方法
- 如何在循环中调用Promise函数并保存其返回值
- AngularJS如何从异步调用返回值
- angularjs从html调用函数返回值
- jQuery deferred:用于延迟函数的返回,直到函数内的异步调用完成+获取返回值
- PHP调用脚本函数,返回值为Uncaught SyntaxError:意外的令牌ILLEGAL
- 从 nodejs 的 mongodb 调用返回值
- ajax调用返回值,但变量为null
- 从ajax调用返回值到javascript
- 如何让此 JSONP 调用返回值
- 使用jquery将ajax调用返回值分配给var
- 如何使函数在返回true或false之前等待ajax调用返回值?
- 与从同步ajax调用返回值混淆
- JSP向ajax调用返回值
- jQuery.getJSON()错误:浏览器链接:调用返回值回调失败:类型错误:无法读取属性'文件'为n
- 浏览器链接:无法调用返回值回调:TypeError:无法读取属性'文件'为null