【问题标题】:"async.forEach" itetarion stop until request get an output"async.forEach" 迭代停止,直到请求得到输出
【发布时间】:2018-01-09 03:43:54
【问题描述】:

除此行之外,此代码完美运行:“inventory[asset.assetid].floatvalue = getFloat”。如您所见,它处于异步模式,并且此行初始化请求以获取某些值,但由于值未定义,因此无法获取。我测试了它,请求中的主要问题也是异步的。所以答案是如何停止异步模式并等待请求返回。

    '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";
    }

});

}

【问题讨论】:

    标签: node.js asynchronous foreach request async.js


    【解决方案1】:

    只需在定义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) 确保您始终触发回调,即 cbDesccbAsset 在每个操作中至少且最多一次。如果您没有正确执行此操作,您的代码将挂起或触发错误。

    (3) 如果Trade.getItemType()Trade.getItemWear()Trade.getInspect()Trade.getInspect() 都是异步的,那么您可能需要使用另一个async 函数(例如async.series()async.parallel() ) 并等待其最终回调执行inventory[asset.assetid] 行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-28
      • 2021-12-07
      • 2020-02-02
      • 1970-01-01
      • 2020-10-24
      • 2014-09-07
      相关资源
      最近更新 更多