简体   繁体   English

在函数外部访问变量的值

[英]Access value of a variable outside a function

I know this question has been asking many times, but I still can't find any solution ! 我知道这个问题已经问了很多遍了,但是我仍然找不到任何解决方案! Here is my code : I'm programming an array of cryptocurrency's values but I'm stuck when I'm trying to create graphs. 这是我的代码:我正在对一组加密货币的值进行编程,但是在尝试创建图形时被卡住了。

ajaxGet("https://api.coinmarketcap.com/v1/ticker/?limit=300", function (reponse) {
    // Transforme la réponse en tableau d'objets JavaScript
    var monnaie = JSON.parse(reponse);
    $("#tableBody").empty();      

    var tr;


    function page1(event) { 

        var timestamp = Math.round(new Date().getTime() / 1000);
        console.log(timestamp);

        for (var i = 0; i < 50; i++) {


            ajaxGet("https://min-api.cryptocompare.com/data/histohour?fsym=" + monnaie[i].symbol + "&tsym=USD&limit=28&aggregate=6&toTs=" + timestamp, function (reponse2) {

                var monnaieGraph = JSON.parse(reponse2)['Data'];
                var points = '';
                var maximum = Math.max.apply(Math,monnaieGraph.map(function(o){return o.high;}))
                var minimum = Math.min.apply(Math,monnaieGraph.map(function(o){return o.low;}))


                for (var j=0; j<=28; j++){
                    var moyenne = ((monnaieGraph[j].high)+(monnaieGraph[j].low))/2;
                    echelle = ((-100/(maximum-minimum))*(moyenne-minimum))+100;

                    points += (j*12) + ',' + echelle + '\n';
                }
            });


            tr = $('<tr/>');
            tr.append("<td>" + monnaie[i].rank + "</td>");
            tr.append("<td>" + "<img class=imageCrypto src=logos/" + monnaie[i].symbol + ".png" + " " + "style=width:37.5px; height:37.5px;" + ">" + "<div class=nomCurr><a href=http://www.google.com/" + monnaie[i].id +">" + monnaie[i].name + "</a>" + "<div>" + monnaie[i].symbol + "</div></div></td>");
            tr.append("<td>" + formatter.format(monnaie[i].price_btc) + " BTC" + "</td>");
            tr.append("<td>" + "$ " + formatter.format(monnaie[i].price_usd) + "</td>");
            tr.append("<td>" + "$ " + formatter.format(monnaie[i].market_cap_usd) + "</td>");
            tr.append("<td>" + formatter.format(monnaie[i].available_supply) + " " + monnaie[i].symbol + "</td>");
            if (Number(monnaie[i].percent_change_24h) > 0) {
                tr.append("<td class=pourcentPositif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-up'" + "</td>");
                //tr.append("<i class=fa fa-caret-up>" + "</i>");
            }
            else {
                tr.append("<td class=pourcentNegatif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-down'" + "</td>");
            }
            tr.append('<td><svg viewBox="0 0 336 100" width=116 height=35><polyline fill=none stroke=#0074d9 stroke-width=6 points="' + points + '"/></svg></div>');
            $('#tableBody').append(tr);

        }
    }

Everything works ! 一切正常! I got an array with all the values I want. 我得到了一个包含所有所需值的数组。

And as I said, I'm trying to add a column of graphs for each currency ! 正如我所说,我正在尝试为每种货币添加一列图表! I tried 3 different code but none of them are working ! 我尝试了3种不同的代码,但没有一个起作用! Here are the 3 codes with an image of each result: 以下是3个代码以及每个结果的图片:

for (var i = 0; i < 50; i++) {


            ajaxGet("https://min-api.cryptocompare.com/data/histohour?fsym=" + monnaie[i].symbol + "&tsym=USD&limit=28&aggregate=6&toTs=" + timestamp, function (reponse2) {

                var monnaieGraph = JSON.parse(reponse2)['Data'];
                var points = '';
                var maximum = Math.max.apply(Math,monnaieGraph.map(function(o){return o.high;}))
                var minimum = Math.min.apply(Math,monnaieGraph.map(function(o){return o.low;}))


                for (var j=0; j<=28; j++){
                    var moyenne = ((monnaieGraph[j].high)+(monnaieGraph[j].low))/2;
                    echelle = ((-100/(maximum-minimum))*(moyenne-minimum))+100;

                    points += (j*12) + ',' + echelle + '\n';
                }
            });


            tr = $('<tr/>');
            tr.append("<td>" + monnaie[i].rank + "</td>");
            tr.append("<td>" + "<img class=imageCrypto src=logos/" + monnaie[i].symbol + ".png" + " " + "style=width:37.5px; height:37.5px;" + ">" + "<div class=nomCurr><a href=http://www.google.com/" + monnaie[i].id +">" + monnaie[i].name + "</a>" + "<div>" + monnaie[i].symbol + "</div></div></td>");
            tr.append("<td>" + formatter.format(monnaie[i].price_btc) + " BTC" + "</td>");
            tr.append("<td>" + "$ " + formatter.format(monnaie[i].price_usd) + "</td>");
            tr.append("<td>" + "$ " + formatter.format(monnaie[i].market_cap_usd) + "</td>");
            tr.append("<td>" + formatter.format(monnaie[i].available_supply) + " " + monnaie[i].symbol + "</td>");
            if (Number(monnaie[i].percent_change_24h) > 0) {
                tr.append("<td class=pourcentPositif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-up'" + "</td>");
                //tr.append("<i class=fa fa-caret-up>" + "</i>");
            }
            else {
                tr.append("<td class=pourcentNegatif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-down'" + "</td>");
            }

            tr.append('<td><svg viewBox="0 0 336 100" width=116 height=35><polyline fill=none stroke=#0074d9 stroke-width=6 points="' + points + '"/></svg></div>');

            $('#tableBody').append(tr);

        }

Inside my "for" loop, I added the ajaxGet, in which I create a variable "points" which get the values from the API scaled for the graph. 在我的“ for”循环中,我添加了ajaxGet,在其中创建了一个变量“ points”,该变量从针对该图缩放的API中获取值。

This code doesn't work, I got the error: "points is not defined". 该代码不起作用,出现错误:“未定义点”。

Here is my 2nd try : 这是我的第二次尝试:

for (var i = 0; i < 50; i++) {

            tr = $('<tr/>');
            tr.append("<td>" + monnaie[i].rank + "</td>");
            tr.append("<td>" + "<img class=imageCrypto src=logos/" + monnaie[i].symbol + ".png" + " " + "style=width:37.5px; height:37.5px;" + ">" + "<div class=nomCurr><a href=http://www.google.com/" + monnaie[i].id +">" + monnaie[i].name + "</a>" + "<div>" + monnaie[i].symbol + "</div></div></td>");
            tr.append("<td>" + formatter.format(monnaie[i].price_btc) + " BTC" + "</td>");
            tr.append("<td>" + "$ " + formatter.format(monnaie[i].price_usd) + "</td>");
            tr.append("<td>" + "$ " + formatter.format(monnaie[i].market_cap_usd) + "</td>");
            tr.append("<td>" + formatter.format(monnaie[i].available_supply) + " " + monnaie[i].symbol + "</td>");
            if (Number(monnaie[i].percent_change_24h) > 0) {
                tr.append("<td class=pourcentPositif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-up'" + "</td>");
                //tr.append("<i class=fa fa-caret-up>" + "</i>");
            }
            else {
                tr.append("<td class=pourcentNegatif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-down'" + "</td>");
            }

            ajaxGet("https://min-api.cryptocompare.com/data/histohour?fsym=" + monnaie[i].symbol + "&tsym=USD&limit=28&aggregate=6&toTs=" + timestamp, function (reponse2) {

                var monnaieGraph = JSON.parse(reponse2)['Data'];
                var points = '';
                var maximum = Math.max.apply(Math,monnaieGraph.map(function(o){return o.high;}))
                var minimum = Math.min.apply(Math,monnaieGraph.map(function(o){return o.low;}))


                for (var j=0; j<=28; j++){
                    var moyenne = ((monnaieGraph[j].high)+(monnaieGraph[j].low))/2;
                    echelle = ((-100/(maximum-minimum))*(moyenne-minimum))+100;

                    points += (j*12) + ',' + echelle + '\n';
                }

                tr.append('<td><svg viewBox="0 0 336 100" width=116 height=35><polyline fill=none stroke=#0074d9 stroke-width=6 points="' + points + '"/></svg></div>');
            });

            $('#tableBody').append(tr);

        }

This time, I added the creation of the column inside the ajaxGet. 这次,我在ajaxGet中添加了该列的创建。 The graphs are ok, but they only appear as a row, on the last row ! 这些图还可以,但是它们仅显示为一行,位于最后一行!

And here is my last try: 这是我最后的尝试:

for (var i = 0; i < 50; i++) {


            ajaxGet("https://min-api.cryptocompare.com/data/histohour?fsym=" + monnaie[i].symbol + "&tsym=USD&limit=28&aggregate=6&toTs=" + timestamp, function (reponse2) {

                var monnaieGraph = JSON.parse(reponse2)['Data'];
                var points = '';
                var maximum = Math.max.apply(Math,monnaieGraph.map(function(o){return o.high;}))
                var minimum = Math.min.apply(Math,monnaieGraph.map(function(o){return o.low;}))


                for (var j=0; j<=28; j++){
                    var moyenne = ((monnaieGraph[j].high)+(monnaieGraph[j].low))/2;
                    echelle = ((-100/(maximum-minimum))*(moyenne-minimum))+100;

                    points += (j*12) + ',' + echelle + '\n';
                }

            tr = $('<tr/>');
            tr.append("<td>" + monnaie[i].rank + "</td>");
            tr.append("<td>" + "<img class=imageCrypto src=logos/" + monnaie[i].symbol + ".png" + " " + "style=width:37.5px; height:37.5px;" + ">" + "<div class=nomCurr><a href=http://www.google.com/" + monnaie[i].id +">" + monnaie[i].name + "</a>" + "<div>" + monnaie[i].symbol + "</div></div></td>");
            tr.append("<td>" + formatter.format(monnaie[i].price_btc) + " BTC" + "</td>");
            tr.append("<td>" + "$ " + formatter.format(monnaie[i].price_usd) + "</td>");
            tr.append("<td>" + "$ " + formatter.format(monnaie[i].market_cap_usd) + "</td>");
            tr.append("<td>" + formatter.format(monnaie[i].available_supply) + " " + monnaie[i].symbol + "</td>");
            if (Number(monnaie[i].percent_change_24h) > 0) {
                tr.append("<td class=pourcentPositif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-up'" + "</td>");
                //tr.append("<i class=fa fa-caret-up>" + "</i>");
            }
            else {
                tr.append("<td class=pourcentNegatif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-down'" + "</td>");
            }

            tr.append('<td><svg viewBox="0 0 336 100" width=116 height=35><polyline fill=none stroke=#0074d9 stroke-width=6 points="' + points + '"/></svg></div>');

            $('#tableBody').append(tr);
            });
        }

I added the declaration of the whole table, inside the ajaxGet ! 我在ajaxGet内添加了整个表的声明! I don't understand the result : This time, the graphs are what I want, but the rest of the array (every columns in every rows) have the value of the 51th coin (but the "graphs" column works), while my variable i is supposed to be 0 我不明白结果:这次,图形是我想要的,但是数组的其余部分(每行中的每一列)具有第51个硬币的值(但是“ graphs”列有效),而我的变量我应该是0

Hope my problem is clear, I'm sorry I can't post images... Thank you for your time ! 希望我的问题很清楚,对不起,我无法发布图片...谢谢您的时间!

I think the first of the three code snippets should work, if you change the following things: 我认为,如果您更改以下内容,则三个代码段中的第一个应该起作用:

The scope of your points variable is limited to the callback function you provide to the ajaxGet function. points变量的范围仅限于您提供给ajaxGet函数的回调函数。 Therefore when you try to use it when building your table, it can't be accessed. 因此,当您尝试在构建表时使用它时,将无法访问它。 That is why you get the error points is not defined . 这就是为什么您points is not defined错误points is not defined Declare the points variable in scope of your for-loop to solve this. 在您的for循环范围内声明points变量以解决此问题。

When building your points you delimit your point pairs by \\n , I'm not sure if that works in your SVG code in this case. 在构建点时,您用\\n分隔点对,在这种情况下,我不确定该点对是否适用于SVG代码。 Maybe try to delimit by a blank space. 也许尝试用空格分隔。

The problem with the SVG images not showing is because apparently you have to reload the actual HTML that you generated to get the SVG images rendered in the browser. SVG图像未显示的问题是因为显然您必须重新加载生成的实际HTML才能在浏览器中呈现SVG图像。 See this related anwer . 看到这个相关的答案 In your case you should reload the HTML of your table every time after a row is added. 根据您的情况,每次添加一行后,都应重新加载表的HTML。 Using jQuery it would look something like this: 使用jQuery看起来像这样:

// Row creation logic...

$('#tableBody').append(tr);
$("#tableBody").html($("#tableBody").html());

Edit: 编辑:

  • Solved scoping and async issues by using closures. 通过使用闭包解决了范围和异步问题。
  • Used separate functions for somewhat improved readability. 使用单独的功能可提高可读性。
  • Used jQuery to build the table and SVG elements. 使用jQuery构建表格和SVG元素。

function getTimestamp() {
    return Math.round(new Date().getTime() / 1000);
}

function getAveragePrice(pricepoint) {
    return (pricepoint.high + pricepoint.low) / 2;
}

function getPointMap(min, max) {
    return function (price, index) {
        var range = max - min;
        var offset = price - min;
        var value = 100 - (offset * 100 / range);

        return `${index * 12},${value}`;
    }
}

function getPoints(prices) {
    var min = Math.min(...prices);
    var max = Math.max(...prices);

    var points = prices.map(getPointMap(min, max));

    return points.join(" ");
}

function getSvg(points) {
    var line = $('<polyline/>');
    line.attr("fill", "none");
    line.attr("stroke", "#0074d9");
    line.attr("stroke-width", 6);
    line.attr("points", points);

    var svg = $('<svg/>');
    svg.attr("viewBox", "0 0 336 100");
    svg.attr("width", 116);
    svg.attr("height", 35);
    svg.append(line);

    return svg;
}

function getCell(content) {
    return $("<td/>").append(content);
}

function getRow(coin, points) {
    // Set id to SortOrder provided by API so 
    // we can use it to add the rows to the 
    // table in the right order.
    var tr = $('<tr/>');
    tr.attr("id", coin.SortOrder);

    tr.append(getCell(coin.SortOrder));
    tr.append(getCell(coin.CoinName));
    tr.append(getCell(`${coin.TotalCoinSupply}`));

    tr.append(getCell(getSvg(points)));

    return tr;
}

function addRow(row, table)
{
    var current = table.children().first();

    // While there is a next row
    while(current.is("tr")) {
        // Check if the rank of current row is 
        // larger than the rank of the row we 
        // want to add.
        if(Number(current.attr("id")) > Number(row.attr("id"))) {
            // If true, add the row before the 
            // current row and we are done.
            current.before(row);
            return;
        }

        // Else check the next row.
        current = current.next();
    }

    // If the table does not contain rows yet or 
    // the end of the table is reached without 
    // finding larger ranks, just add the row at 
    // the end.
    table.append(row);
}

function getHistoryCallback(table, coin) {
    return function (history) {
        var prices = history.Data.map(getAveragePrice);
        var points = getPoints(prices);
        var row = getRow(coin, points);

        addRow(row, table);
        table.html(table.html());
    }
}

function sortCoins(a, b) {
    return a.SortOrder - b.SortOrder;
}

function getCoinsCallback(table) {
    return function (coinlist) {
        var coins = Object.values(coinlist.Data).sort(sortCoins);

        table.empty();

        for (var i = 0; i < 10; i++) {
            var coin = coins[i];

            var url = "https://min-api.cryptocompare.com/data/histohour";
            var data = {
                fsym: coin.Symbol,
                tsym: "USD",
                limit: 28,
                aggregate: 6,
                toTs: getTimestamp()
            };
            var callback = getHistoryCallback(table, coin);

            $.getJSON(url, data, callback);
        }
    }
}

function populateTable(table_id) {
    var table = $(`#${table_id}`);

    var url = "https://min-api.cryptocompare.com/data/all/coinlist";
    var callback = getCoinsCallback(table);

    $.getJSON(url, callback);
}

$(document).ready(function () {
    populateTable("tableBody");
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM