为什么console.log调用的显示顺序与编写顺序不同?

时间:2015-04-22 00:40:48

标签: javascript node.js

我是Node.js的新手,我想我不明白它应该如何工作。我正在使用蒸汽贸易,在我看来,这应首先通过一个交易报价,然后对于我将要收到的每个项目,它加载他们的库存并将其与他们的库存进行比较,直到找到匹配的项目和打印它。但是,它首先加载所有要约,然后加载所有库存。

steam.on('webSessionID', function (sessionID) {
    steam.webLogOn(function (newCookie) {
        offers.setup({
            sessionID: sessionID,
            webCookie: newCookie
        }, function (err) {
            if (err) {
                throw err;
            }
            offers.getOffers({
                get_received_offers: 1,
                active_only: 1,
            }, function (error, body) {
                if (body.response.trade_offers_received) {
                    body.response.trade_offers_received.forEach(function (offer) {
                        console.log('TRADE OFFER')
                        offer.items_to_receive.forEach(function (offerItem) {
                            offers.loadPartnerInventory({
                                contextId: 2,
                                partnerSteamId: offer.steamid_other,
                                tradeOfferId: offer.tradeofferid,
                                appId: 730
                            }, function (err, items) {
                                var item;
                                // Load tradable items in inventory
                                for (var i = 0; i < items.length; i++) {
                                    if (items[i].tradable) {
                                        item = items[i];
                                        //if item matches item from their inventory we can get the market name
                                        if (item.id == offerItem.assetid){
                                            console.log(item.market_name)
                                        }
                                    }
                                }
                            });
                        });
                    });
                }
            });
        });


    });
});

输出:

TRADE OFFER
TRADE OFFER
TRADE OFFER
Sticker Capsule 2
Sticker Capsule 2
Sticker Capsule 2

我的期望:

TRADE OFFER
Sticker Capsule 2
TRADE OFFER
Sticker Capsule 2
TRADE OFFER
Sticker Capsule 2

有人可以向我解释发生了什么事吗?

e:这令人讨厌的例子

                        for (var i = 0; i < items.length; i++) {
                            if (items[i].tradable) {
                                item = items[i];
                                //if item matches item from their inventory we can get the market name
                                if (item.id == offerItem.assetid){
                                    // Configure the request
                                    console.log(item.market_name)
                                    var options = {
                                        url: 'http://steamcommunity.com/market/priceoverview/?country=US&currency=1&appid=730&market_hash_name=' + item.market_name,
                                        method: 'GET',
                                        headers: headers
                                    }
                                    // Start the request
                                    request(options, function (error, response, body) {
                                        result = JSON.parse(body)
                                        if (result['success'] == true) {
                                            console.log(item.market_name + " valued at " + result['median_price'])
                                        }
                                    })
                                }
                            }
                        }

输出:

429313829
Sticker Capsule 2
429316197
Sticker Capsule 2
429315519
Sticker Capsule 2
Nova | Predator (Field-Tested) valued at &#36;0.09
Nova | Predator (Field-Tested) valued at &#36;0.09
Nova | Predator (Field-Tested) valued at &#36;0.09

如你所见,该项目应该是Sticker Capsule 2,而不是新星捕食者

1 个答案:

答案 0 :(得分:2)

要让它们按照您的预期顺序运行,您需要考虑节点回调的异步性质。

body.response.trade_offers_received.forEach(function (offer) {

可以使用fantastic async library替换为类似内容。

require('async').series(body.response.trade_offers_received, function(offer, callback){
  //process the offer variable
  callback(); // <- call this to tell async that this item is done being processed.
});

此外,您肯定需要/希望在某些时候处理错误,并且可能希望在最终回调中收集所有操作的结果。

require('async').series(body.response.trade_offers_received, function(offer, callback){
  loadPartnerInventoryAsyncCall({offer: offer}, function(err, someOtherResult){
    if (err) {
      return callback(err);
    }

    //process the offer variable
    callback(null, someOtherResults); // <- call this to tell async that this item is done being processed.
  });
}, function(err, allResults){
  if (err){
    console.log('one of my series functions had an error', err);
  }

  //do something with allResults, if you want
});

尝试用一个简单的例子澄清异步请求:

['google.com','yahoo.com','bing.com'].forEach(function(url){
  require('request').get(url, function(err, result){
    console.log(result);
  });
});

由于网络延迟,我不知道首先会记录哪个页面结果!他们可以按任何顺序出来!