2016-07-24 5 views
0

Я хочу изменить Тэги формат, который я получаю в форме одной из коллекций. Тэги данные содержат некоторые KC идентификаторы в массиве, который я использую, чтобы получить KC данных и вставить в TagUnit, чтобы получить окончательный формат ответа.Требуется нулевой запрос обратного вызова для нумерации

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

Вы смотрели в [обещания] (http://www.html5rocks.com/en/tutorials/es6/promises/?redirect_from_locale=de)? Вы правы, что ваша проблема связана с циклом событий. 'newTags' не вычисляется полностью наиболее вероятно при вызове' response.send'. – 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 
}); 

P.S. Возможно, код содержит ошибки. Я не могу это проверить.

 Смежные вопросы

  • Нет связанных вопросов^_^