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

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

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 $0.09 Nova | Predator (Field-Tested) valued at $0.09 Nova | Predator (Field-Tested) valued at $0.09 

正如你所看到的,物品应该是贴纸胶囊2,而不是新星捕食者

为了让它们按照您期望的顺序运行,您需要考虑节点callback的asynchronous性质。

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

可以用类似这样的东西使用奇妙的asynchronous库 。

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

此外,您肯定会在某个时间点需要/希望进行error handling,并且可能希望在最终callback中收集所有操作的结果。

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

试图用一个简单的例子来澄清asynchronous请求:

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

由于networking延迟,我不知道哪个页面的结果将首先得到logging! 他们可以以任何顺序出来!