【问题标题】:Asynchronous JavaScript and functions异步 JavaScript 和函数
【发布时间】:2016-01-17 20:55:49
【问题描述】:

我正在编写计算已发送商品价格的蒸汽机器人。我无法正确使用函数。我想从 URL 中获取价格,然后将其添加到 console.log。

我做不到,因为console.log在循环之前执行。

我真的是 Javascript 的新手,我无法修复它:(

var whole_price = 0;
for(var i=0 ; i<offer.itemsToReceive.length; i++){
    getPrice(offer.itemsToReceive[i].market_hash_name, function(price){
        whole_price += price;
    }); 
}
console.log('Accepted offer from ' + offer.partner + ' with ' + offer.itemsToReceive.length + ' items valued as '+whole_price+'$.' );

获取 URL 价格的函数:

function getPrice(name, callback){
    name = name.replace(/\ +/g, '%20');
    var url = 'http://steamcommunity.com/market/priceoverview/?currency=1&appid=730&market_hash_name='+name;
    var price = 0;


    request(url ,function(error, res, body){
        var useCSGOBACKPACK = false;
        if(!error && res.statusCode == 200){
            body = JSON.parse(body);
            if(body.success == true){
                price = body.median_price.substr(1);
            }else{
                useCSGOBACKPACK = true;
            }
        }else{
            useCSGOBACKPACK = true;
        }

        if(useCSGOBACKPACK==true){
            url = 'http://csgobackpack.net/api/GetItemPrice/?id='+name+'&currency=USD';
            request(url, function(error, res, body){
                body = JSON.parse(body);
                price = body.median_price;
            });
        }

        callback(price);
    });

}

【问题讨论】:

  • whole_price variable can't be accessed inside callback 为什么会这样?
  • 哇,我修改了代码,它可以(可能在我打错之前),但console.log仍然在循环之前执行。
  • 那是因为getPrice 函数是异步的。您必须计算已完成的回调数量,并且仅在 count == offer.itemsToReceive.length 时记录该值。或者您可以使用async 库或一些承诺库并等待所有回调。 github.com/caolan/async

标签: javascript node.js steam steambot


【解决方案1】:

做这种事情的最好方法是......

var whole_price = 0;
var requestsMade = 0;
for(var i=0 ; i<offer.itemsToReceive.length; i++){
    requestsMade++;
    getPrice(offer.itemsToReceive[i].market_hash_name, function(price){
        whole_price += price;
        requestsMade++;

        if(requestsMade == offer.itemsToReceive.length-1)
        {
            console.log(YOUR MESSAGE);
        }
    }); 
}

这基本上是确保在所有请求都已发出并得到响应之前,您不会记录消息。这是因为即使所有调用都按特定顺序进行,它们也可能以不同的顺序完成。

【讨论】:

    【解决方案2】:

    您应该考虑使用async library,让您的生活更轻松。不要重新发明轮子!

    var whole_price = 0;
    
    async.each(offer.itemsToReceive, function (item, next) {
    
        getPrice(item.market_hash_name, (price) => {
            whole_price += price;
            next();
        });
    
    }, function () {
    
        console.log(whole_price);
    });
    

    【讨论】:

      猜你喜欢
      • 2018-09-07
      • 2017-08-01
      • 2021-12-20
      • 1970-01-01
      • 2018-09-19
      • 1970-01-01
      • 2012-02-25
      • 2014-10-28
      • 1970-01-01
      相关资源
      最近更新 更多