2016-07-24 42 views
0

我想更改標籤格式,我從其中一個集合中獲取。 標籤數據包含在陣列中的一些KC IDS裏面我是用得到KC數據和TagUnit插入得到最終響應的格式。節點for循環回調所需

var newTags = Tags.map(function(TagUnit) { 
    for (var i = 0; i < TagUnit.kcs.length; i++) { 
     KCArray = []; 
     KC.findById(TagUnit.kcs[i], function(error, data) { 
      KCMap = {}; 
      KCMap['kc_id'] = data._id; 
      KCMap['kc_title'] = data.title; 
      KCArray.push(KCMap); 
      if (KCArray.length == TagUnit.kcs.length) { 
       TagUnit.kcs = KCArray; 
      } 
     }); 
    } 
    return TagUnit; 
}); 

response.send(JSON.stringify(newTags)); 

但我沒有得到期望的結果。響應發出標籤數據在初始而不是格式化的形式。我想這是由於事件循環。如果有人能幫助我,我將不勝感激。

**編輯:**我使用MongoDB作爲數據庫和貓鼬作爲ORM。

+1

你看過[promise](http://www.html5rocks.com/en/tutorials/es6/promises/?redirect_from_locale=de)嗎?你說得對,你的問題是由事件循環引起的。當調用'response.send'時,'newTags'不會被最完全計算。 – markusthoemmes

回答

1

我會建議使用承諾來管理你現在是ES6標準的異步操作。你不會說你正在使用什麼數據庫(它可能已經有一個基於承諾的界面)。如果沒有,那麼我們手動promisify KC.findById()

function findById(key) { 
    return new Promise(function(resolve, reject) { 
     KC.findById(key, function(err, data) { 
      if (err) return reject(err); 
      resolve(data); 
     }); 
    }); 
} 

然後,假設你可以做所有這些發現並行操作,您可以使用Promise.all()既跟蹤,當他們完成所有的工作,並命令他們爲你。

var allPromises = Tags.map(function(TagUnit) { 
    var promises = TagUnit.kcs.map(function(key) { 
     return findById(key).then(function(data) { 
      // make resolved value be this object 
      return {kc_id: data._id, kc_title: data.title}; 
     }); 
    }); 
    // this returns a promise that resolves with an array of the kc_id and kc_title objects 
    return Promise.all(promises).then(function(results) { 
     return { 
      _id: TagUnit._id, 
      kcs: results 
     }; 
    }); 
}); 

// now see when they are all done 
Promise.all(allPromises).then(function(results) { 
    response.send(JSON.stringify(results)); 
}).catch(function(err) { 
    // send error response here 
}); 
+0

我正在測試解決方案。同時僅供參考,我的數據庫是mongoDB,ORM是貓鼬。 – Rusty

+0

@Rusty - 我有點難以告訴你想要什麼樣的最終結果。這段代碼給了你一個對象數組數組,每個對象包含'kc_id'和'kc_title',因爲這就是我認爲你的原始代碼試圖生成的東西。 – jfriend00

+0

我希望**響應**以以下格式進行。 '{「tag_id」:「nienemk29290hu38」,「kcs」:{「kc_id」:「nmdkwmswmwjm4944」,「kc_title」:「ABC」}'。你的解決方案似乎幾乎接近我正在做最後的格式化有點困難。 – Rusty

1

您可以使用承諾或Async模塊

var async = require('async'); 
... 
function getKC (kc, callback) { 
    KC.findById(kc, function(err, data) { 
     if (err) 
      return callback(err); 

     callback(null, {kc_id: data._id, kc_title: data.title}) 
    }); 
} 

function getKCs (tag, callback) { 
    async.map(tag.kcs, getKC, callback); 
} 

async.map(Tags, getKCs, function(err, results){ 
    if (err) 
     return console.log(err.message); 

    res.json(results); // or modify and send 
}); 

附:也許,代碼包含錯誤。我無法測試它。