如何获得此JSONP调用以返回值? [英] How can I get this JSONP call to return a value?

查看:139
本文介绍了如何获得此JSONP调用以返回值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下功能的目的是访问Yahoo服务器上的脚本并查找实时货币兑换率,该汇率随后将用于处理客户的购买.

The purpose of the following functions are to access a script on Yahoo's servers and lookup a live currency conversion rate which will later be used to process a customer's purchases.

我可以访问JavaScript警报中的费率,但似乎无法将它们返回给最初称为getRate()函数的Jquery方法.

I'm able to access the rates in the JavaScript alert but I can't seem to return them to the Jquery method which originally called the getRate() function.

我已经在parseExchangeRate()函数的末尾尝试了标准的return rate;,但该方法不起作用.我还尝试将rate设置为parseExchangeRate()中的全局变量,但这也不起作用.

I've tried a standard return rate; at the end of the parseExchangeRate() function, which doesn't work. I've also tried setting rate as a global variable within parseExchangeRate() but that doesn't work either.

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函数中访问rate时,Firebug通知我rate是未定义的.

Firebug informs me the rate is undefined when I try to access it in Jquery function.

我尝试的另一件事是将http请求的最后一个参数设置为callback=rate=parseExchangeRate,这(也不奇怪)也不起作用.

The other thing I tried was setting the last parameter of the http request to callback=rate=parseExchangeRate which (not surprisingly) didn't work either.

更新

@Relfor解决了最初的问题,即rate在全局范围内未正确声明为全局变量.我修复了该问题,然后发现了另一个在下面也已确定的问题,即在调用getRate()之后(可能需要大约2000ms来更新变量rate),脚本立即继续运行,而无需等待进行更新并使用费率,而不管其是否准备就绪.

@Relfor solved the original problem, which was that rate was not properly declared as a global variable in the global scope. I fixed that and then found a further issue which some have also identified below, which is that after getRate() is called (which can take about 2000ms to update the variable rate), the script moves on immediately without waiting for rate to be updated and uses rate regardless of whether it's ready.

我尝试过尝试使用window.setInterval来创建延迟来解决此问题,当我注意到它们即使在我已经接受@Relfor的回答的情况下仍然在线程中处于活动状态时,所以我更喜欢把它带回这里,以便我们进行这项工作时,其他人也可以从解决方案中受益.

I tried was attempting to use window.setInterval to create a delay to solve this, when it came to my attention that their was still activity in the thread even though I'd already accepted @Relfor's answer, so I'd prefer to bring it back here so that when we have this working, others can benefit from the solutions.

有一个最终的(我希望-最终!)问题,这是为了简化原始发帖问题,我省略了我实际上是想从中获得两个比率的信息.雅虎! (可能还有更多计划),因此,我在循环中调用getRate(),如下所示:

There is one final (I hope - final!) problem and that is that in order simplify the original question for posting, I ommitted to disclose that I'm actually trying to get two rates from Yahoo! (which possibly a few more planned) and therefore, I'm calling getRate() in a loop as follows:

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()有何启示?

It was suggested that I move /* Do stuff with the rates */ to inside the function parseExchangeRate() but not sure whether that advice would still stand given my revelations about calling getRate() in a loop?

更新3(已替换更新2)

我在这里创建了一个JSbin: http://jsbin.com/udikas/3/edit与以上所述相比,除了这两个问题外,它们似乎都有效:

I have created a JSbin here: http://jsbin.com/udikas/3/edit with the above which apart from these two issues appears to be working:

1)超时机制似乎无法正常工作.

1) The timeout mechanism appears not to be working.

2)在第33行的此行alert('start timer (' + x +')');上,如果没有此计时器,计时器似乎就不会启动!我不知道为什么,但是我不能把那行留在那儿.

2) On line 33 this line alert('start timer (' + x +')'); without which, the timer doesn't seem to start! I have no idea why, but I can't leave that line in.

推荐答案

变量rate尚未定义

$(function() {

    getRate('USD', 'PHP');
    xRatePHP = rate;

    /* Do stuff with rate */

});

研究完代码后,似乎在parseExchange(data)函数中将速率定义为

after studying your code it seems that rate is defined in the parseExchange(data) function as

function parseExchangeRate(data) {

    var name = data.query.results.row.name;
    rate = parseFloat(data.query.results.row.rate, 10);

    alert("Exchange rate " + name + " is " + rate);

}

如果您希望可以从函数名称空间访问速率而不在内部声明速率,则必须在全局名称空间中指定速率,该名称空间位于任何函数或循环之外.

if you want rate to be accessible from the function namespaces without declaring them from within then the rates would have to specified in the global namespace, which is outside any of the functions or loops.

编辑:名称空间问题已解决,我给出的答案已被接受,但是我想在此处添加有关您正在处理的代码的详细信息.它是从以下要点摘录的: https://gist.github.com/henrik/265014

Edit: The namespace problem has been solved and the answer I've given has been accepted, however I would like to add details about the code you are handling here. It has been taken from the gist here: https://gist.github.com/henrik/265014

parseExchangeRate存在的原因及其上下文乍看起来似乎很神秘,尽管它的存在是JSONP请求与响应返回的数据之间的主要连接.

the reason why parseExchangeRate exists and the context of it can seem mysterious at first glance, albeit its existence is the primary connection between your JSONP request and the data returned by the response.

如果您仔细查看请求:

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请求完成时,将调用parseExchangeRate.

(I broke the link up into many lines to make it easier to read)
Carefully look at the last segment of the url: callback=parseExchangeRate
This here is the connection, when the JSONP request is complete parseExchangeRate will be called.

让我再次显示代码:

$(function() {

    getRate('USD', 'PHP');
    xRatePHP = rate;

    /* Do stuff with rate */

});

我们应该分手:

  • getRate('USD', 'PHP')的工作是加载具有各自货币类型"USD"和"PHP"的JSONP
  • xRatePHP = raterate的右侧分配给xRatePHP. 但这行给我们带来了问题!我们的控制台好友告诉我们rate未定义!
  • getRate('USD', 'PHP') does the job of loading the JSONP with the respective currency types of 'USD' and 'PHP'
  • xRatePHP = rate assigns the right hand side which is rate to xRatePHP. But this line gave us a problem! our console pal told us that rate is undefined!

真相:控制台先生没有说谎,rate实际上是未定义的,但是控制台先生没有您提供任何其他命令",则会回答rate实际上已定义.这是魔法吗?

The truth: mr.console did not lie, rate is actually undefined, however mr.console without any further commands given by you a few moments later if asked again would reply that rate is actually defined. Is this magic?

实际上是在您离开这条线的时间之间

What is actually happening is that between the time you go from this line

getRate('USD', 'PHP');

xRatePHP = rate;

mr.yahoo的JSONP响应尚未返回,这就是为什么发布xRatePHP = raterate似乎未定义的原因.

the JSONP response from mr.yahoo hasn't yet come back, which is why when xRatePHP = rate is issued rate seems to be undefined.

硬编码解决方案
让我们对使用rate之前的代码进行硬编码等待一段时间,以便我们知道mr.yahoo做出了响应,setTimeout将在这里为我们提供帮助:

Hard Code Solution
Let us hard code a duration for our code to wait before using rate so that we know that mr.yahoo responded, setTimeout will helps us here:

getRate('USD', 'PHP');
setTimeout(function(){alert(rate)}, 2000);

现在一切正常!在以下位置查看演示: http://jsbin.com/udikas/1/edit

and everything works now! check the demo at: http://jsbin.com/udikas/1/edit

软代码
您是否考虑过Yahoo先生需要2000毫秒以上的回复时间的情况?甚至比这还小? (yahoo相当快!)让我们采取另一种方法,这将使我们使用rate 确切时刻,我们使用parseExchangeRate

Soft Code
did you ever consider the case where mr.yahoo takes more than 2000 ms to respond? or maybe even lesser than that? (yahoo is pretty fast!) let us instead take a different approach, this will let us use rate the exact moment we calculate it with parseExchangeRate

为此,我们将必须添加来自parseExchangeRate的回调:

for this we will have to add a callback from 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

a demo of this can be found at http://jsbin.com/udikas/2/edit

记住硬编码setTimeouts不好玩,所以让我们从您的代码中删除manageTimerq以及其他此类元素,相反,我们可以:

Remember hard coding setTimeouts isn't fun, so let us remove that, manageTimer, q, and other such elements from your code, instead we can have:

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

-Relfor

这篇关于如何获得此JSONP调用以返回值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆