2017-08-02 3 views
0

このコードは、この行のほかに "inventory [asset.assetid] .floatvalue = getFloat"というコードで完全に動作します。あなたが見ることができるように、それは非同期モードにあり、この行は何らかの値を取得する要求を初期化しますが、値は未定義です。私はそれをテストし、要求の主な問題は非同期でもあります。したがって、非同期モードを停止してリクエストの戻りを待つ方​​法が答えです。"async.forEach" itetarionは要求が出力されるまで停止します

'use strict' 

    const config = require('../config'); 
    const request = require('request'); 
    const async = require('async'); 
    const Trade = require('./index'); 

    const MAX_RETRIES = 3; 
    const API_URL = 'https://api.steamapis.com/steam/inventory'; 
    const floaturl = 'https://api.csgofloat.com:1738/'; 




    Trade.prototype.getInventory = function getInventory(steamID64, appID, contextID, callback, retries) { 


request(`${API_URL}/${steamID64}/${appID}/${contextID}?api_key=${config.SteamApisKey}`, (error, response, body) => { 
    if (!error && response.statusCode === 200) { 
     const items = JSON.parse(body) 
     const assets = items.assets 
     const descriptions = items.descriptions 

     const inventory = {} 



     if (descriptions && assets) { 

      async.forEach(descriptions, (description, cbDesc) => async.forEach(assets, (asset, cbAsset) => { 

       if (description.classid === asset.classid && description.tradable && description.marketable && description.market_hash_name.indexOf('Souvenir') === -1) { 
        if (typeof inventory[asset.assetid] !== 'undefined') { 
         return true 
        } 
        const type = Trade.prototype.getItemType(description.market_hash_name, description.type) 
        const wear = Trade.prototype.getItemWear(description.market_hash_name) 
        const inspect = Trade.prototype.getInspect(steamID64, asset.assetid, description.actions) 
        const getFloat = Trade.prototype.getFloat(inspect, asset.assetid, function(_float){ 

         var data = String(_float); 
         inventory[asset.assetid].floatvalue = data; // inside the callback, at this moment judging by the consol the data is defined,but outside the callback the data is not appreciated to inventory[asset.assetid].floatvalue 




        }); 




        inventory[asset.assetid] = asset 
        inventory[asset.assetid].item_type = type 
        inventory[asset.assetid].item_wear = wear 
        inventory[asset.assetid].inspect = inspect 
        inventory[asset.assetid].floatvalue = getFloat // this line does not work properly 
        inventory[asset.assetid].data = { 
         background: description.background_color, 
         image: description.icon_url, 
         tradable: description.tradable, 
         marketable: description.marketable, 
         market_hash_name: description.market_hash_name, 
         type: description.type, 
         color: description.name_color, 
        } 

       } 



       return cbAsset() 
      }, cbDesc)) 

     } 


     return callback(null, inventory) 
    } 














    let retry = retries 
    if (typeof retries === 'undefined') { 
     retry = 0 
    } 
    retry += 1 
    if (retry <= MAX_RETRIES) { 
     return Trade.prototype.getInventory(steamID64, appID, contextID, callback, retries) 
    } 
    let statusCode = null 
    if (typeof response !== 'undefined' && typeof response.statusCode !== 'undefined') { 
     statusCode = response.statusCode 
    } 
    return callback({ error, statusCode }) 
}) 
} 

Trade.prototype.getInventories = function getInventories(params, callback) { 
const inventories = {} 
async.each(params, (user, cb) => { 
    Trade.prototype.getInventory(user.steamID64, user.appID, user.contextID, (err, data) => { 
     inventories[user.id] = {} 
     inventories[user.id] = { 
      error: err, 
      items: (!err) ? Object.keys(data).map(key => data[key]) : null, 
     } 
     cb() 
    }) 
},() => { 
    callback(inventories) 
}) 
} 

Trade.prototype.getItemType = function getItemType(marketHashName, type) { 
if (marketHashName.indexOf('Key') !== -1) { 
    return { value: 0, name: 'key' } 
} 
if (marketHashName.indexOf('★') !== -1) { 
    return { value: 1, name: 'knife' } 
} 
if (
    type.indexOf('Classified') !== -1 || 
    type.indexOf('Contraband') !== -1 || 
    type.indexOf('Covert') !== -1 
) { 
    return { value: 2, name: 'rare_skin' } 
} 
if (
    type.indexOf('Consumer Grade') !== -1 || 
    type.indexOf('Base Grade') !== -1 || 
    type.indexOf('Graffiti') !== -1 || 
    type.indexOf('Sticker') !== -1 || 
    type.indexOf('Industrial Grade') !== -1 
) { 
    return { value: 4, name: 'misc' } 
} 
return { value: 3, name: 'weapon' } 
} 

Trade.prototype.getItemWear = function getItemWear(marketHashName) { 
if (marketHashName.indexOf('Factory New') !== -1) { 
    return 'FN' 
} 
if (marketHashName.indexOf('Minimal Wear') !== -1) { 
    return 'MW' 
} 
if (marketHashName.indexOf('Field-Tested') !== -1) { 
    return 'FT' 
} 
if (marketHashName.indexOf('Well-Worn') !== -1) { 
    return 'WW' 
} 
if (marketHashName.indexOf('Battle-Scarred') !== -1) { 
    return 'BS' 
} 
return false 
} 

Trade.prototype.getInspect = function getInspect (steamID64, assetid, actions) { 
let inspectLink = null;           
if (actions) { 
    for (const a in actions) { 
     if (actions[a].name.indexOf('Inspect') !== -1) { 
       inspectLink = actions[a].link 
       inspectLink = inspectLink.replace('%owner_steamid%', steamID64) 
       inspectLink = inspectLink.replace('%assetid%', assetid) 
     } 
    } 
} 
return inspectLink 
} 

Trade.prototype.getFloat = function getFloat (adding, callback) { 

request ("https://api.csgofloat.com:1738/?url=" + adding, (error, response, body) => { 

    if (!error && response.statusCode == 200) { 

     var floatBody = JSON.parse(body); 
     var float = floatBody["iteminfo"]["floatvalue"]; 
     var id = id; 
     if (float != "") { 

      callback(float); 
     } else { 
      return "wrong"; 
     } 
    } else { 
     console.log('something goes wrong'); 
     return "wrong"; 
    } 

}); 

} 

答えて

0

だけdataが定義されているコールバック内部inventory[asset.assetid]ラインのブロックを移動させます。

if (
    description.classid !== asset.classid || 
    !description.tradable || 
    !description.marketable || 
    description.market_hash_name.indexOf('Souvenir') > -1 
) { 
    return cbAsset() 
} 

if (typeof inventory[asset.assetid] !== 'undefined') { 
    return cbAsset() 
} 

const type = Trade.prototype.getItemType(description.market_hash_name, description.type) 
const wear = Trade.prototype.getItemWear(description.market_hash_name) 
const inspect = Trade.prototype.getInspect(steamID64, asset.assetid, description.actions) 
const getFloat = Trade.prototype.getFloat(inspect, asset.assetid, function(_float){ 
    var data = String(_float); 
    inventory[asset.assetid].floatvalue = data; 
    inventory[asset.assetid] = asset 
    inventory[asset.assetid].item_type = type 
    inventory[asset.assetid].item_wear = wear 
    inventory[asset.assetid].inspect = inspect 
    inventory[asset.assetid].data = { 
     background: description.background_color, 
     image: description.icon_url, 
     tradable: description.tradable, 
     marketable: description.marketable, 
     market_hash_name: description.market_hash_name, 
     type: description.type, 
     color: description.name_color, 
    }; 
    return cbAsset(); 
}); 

サイドの発言:

(1)私はいつも汚いコードを避けるためにreturn earlyへのより良いを見つけます。

(2)コールバック(つまり、cbDescおよびcbAsset)が常に少なくとも1回、各操作で1回トリガーされるようにしてください。これを正しく行わないと、コードがハングしたり、エラーが発生したりします。

(3)Trade.getItemType()Trade.getItemWear()Trade.getInspect()、およびTrade.getInspect()はすべて非同期である場合、あなたはおそらく別のasync機能(のようなasync.series()async.parallel())を使用してinventory[asset.assetid]ラインを行うために、その最後のコールバックを待つ必要があります。

関連する問題