Можно ли избежать нескольких слоев вложенных обратных вызовов при сохранении в Mongoose? - PullRequest
0 голосов
/ 09 января 2012

У меня есть две коллекции, первая с массивом ссылочных документов id во второй коллекции.

Есть определенное место, где я хочу создать новый DocumentType, затем новый Document, который ссылается на DocumentType и, наконец, обновить исходный DocumentType для ссылки на новый Document.

A DocumentType может иметь много Documents, но Document может иметь только один DocumentType. Причина, по которой я хочу иметь ссылку в обоих местах, заключается в упрощении более сложных запросов в дальнейшем.

Мой вопрос: есть ли лучший способ написать это с помощью mongoose, чем иметь эти множественные вложенные обратные вызовы.

Я собрал простой пример для демонстрации. В реальных данных больше данных, и поэтому я не хочу, чтобы Document s был встроен в DocumentType s или наоборот.

var DocumentTypeSchema = new Schema({
    name:   String
  , desc:   String
  , documents:  [{type: Schema.ObjectId, ref: 'Document'}]
  , ...
});

var DocumentSchema = new Schema({
    title:    String
  , doctype:  {type: Schema.ObjectId, ref: 'DocumentType'}
  , ...
});

var Document = mongoose.model('Document', DocumentSchema);
var DocumentType = mongoose.model('DocumentType', DocumentTypeSchema);

// Begin the nested callbacks
// Create a document type
var type = new DocumentType({...});

// Save document type
type.save(function(err) {

  // Create new document
  var document = new Document({
      doctype: type.id
    , ...
  });

  // Save document
  document.save(function(err) {

    // Update document type
    DocumentType.update({_id: document.doctype}, {'$addToSet': {documents: document.id}}, function(err) {});
  });
});

Спасибо за вашу помощь

Ответы [ 2 ]

1 голос
/ 10 января 2012

Я бы сказал, что, как правило, нет лучшего способа синхронной обработки.Упомянутая Jani функция series библиотеки async является хорошим способом сгладить это, но я думаю, что в целом неплохо придерживаться структуры обратного вызова - она ​​делает область видимости очень ясной и уменьшает ваши внешние зависимости - если толькоВложение становится абсурдным, или вам нужна асинхронность.Ваше вложение не абсурдно, хотя вы могли бы рассмотреть async.parallel в будущем.Если вы создаете два новых экземпляра и сохраняете атрибуты в обоих, нет смысла делать это синхронно.Вместо этого, что-то вроде этого:

    async.parallel({
        type: function(callback) {
            var type = new DocumentType({...});
            type.save(function(err) {callback(null, type)});
        },
        document: function(callback) {
            var document = new Document({...});
            document.save(function(err) {callback(null, document)});
        }
    },
    function(err, results) {
        results.document.doctype = results.type.id;
        results.document.save();
        DocumentType.update(
          {_id: results.type},
          {'$addToSet': {documents: results.document.id}},
          function(err) {}
        );
    });

Это требует дополнительного сохранения, и, честно говоря, может быть глупым для такой задачи с таким небольшим снижением производительности, но это иллюстрирует хороший подход для асинхронной обработки и универсальностьасинхронная библиотека.

1 голос
/ 09 января 2012

Вы можете использовать что-то вроде функции series node-async для запуска каждого обратного вызова после друг друга. Таким образом, вам не нужно их вкладывать.

https://github.com/caolan/async

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...