2016-01-17 3 views
0

Я пишу паровой бот, который вычисляет цену отправленных предметов. Я не могу правильно использовать функции. Я хочу получить цену от URL-адреса, чтобы добавить его и console.log.Асинхронный JavaScript и функции

Я не могу этого сделать, потому что 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); 
    }); 

} 
+1

Нельзя получить доступ к переменной 'whole_price внутри обратного вызова' Почему это? – Cristy

+0

Вау, я изменил код, и он может (возможно, до того, как я сделал опечатку), но все же console.log выполняется перед циклом. – irqize

+1

Это потому, что функция 'getPrice' является асинхронной. Вы должны подсчитать количество завершенных обратных вызовов и регистрировать только значение, когда 'count == offer.itemsToReceive.length'. Или вы можете использовать библиотеку 'async' или библиотеку обещаний и ждать всех обратных вызовов. https://github.com/caolan/async – Cristy

ответ

3

Лучший способ сделать что-то вроде этого это ...

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); 
     } 
    }); 
} 

это, в основном, убедитесь, что вы не заходите меня в систему ssage до тех пор, пока все запросы не будут сделаны и не будут удовлетворены. Это связано с тем, что, хотя все вызовы выполняются в определенном порядке, они могут выполняться в другом порядке.

+0

Спасибо, ребята, вы спасли мое дно: D – irqize

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); 
}); 
Смежные вопросы