2016-05-03 3 views
1

So, hier ist der Deal finden:kann keine einfache Möglichkeit, aus mehreren async für jeden Knoten js (Segel)

Ich habe ein Array von Objekten mit einem Kind Array von Objekten

askedAdvices 
    askedAdvice.replayAdvices 

I sind Schleifen des Eltern und foreach Schleife Trog den childs Trog und() zwei obejcts (ich bin mit Segeln) bevölkern müssen

Das Kind sieht aus wie:

askedAdvices = { 
    replayAdvices : [{ 
     bookEnd : "<ID>", 
     user : "<ID>" 
    }] 
    } 

Also mein Ziel ist es, bookEnd und Benutzer mit zwei findOne Abfragen zu radeln und zu bevölkern, aber ich werde verrückt nach der Callback-Hölle. Hier ist das Model Code:

AskedAdvices Modell

module.exports = { 
    schema : false, 
    attributes: { 
    bookStart : { 
     model : 'book' 
    }, 
    replayAdvices : { 
     collection: 'replybookend' 

    }, 
    user : { 
     model : 'user', 
     required : true 
    }, 
    text : { 
     type : "text" 
    } 
    } 
}; 

ReplyBookEnd Modell

module.exports = { 
    schema : false, 
    attributes: { 
    bookEnd : { 
     model : 'book' 
    }, 
    user : { 
     model : 'user', 
     required : true 
    }, 
    text : { 
     type : "text" 
    } 
    } 
}; 

Hier ist die Methode Code:

getAskedAdvices : function(req, res) { 

    var queryAskedAdvices = AskedAdvices.find() 
     .populate("replayAdvices") 
     .populate("user") 
     .populate("bookStart") 

    queryAskedAdvices.exec(function callBack(err,askedAdvices){ 

     if (!err) { 
      askedAdvices.forEach(function(askedAdvice, i){ 

       askedAdvice.replayAdvices.forEach(function(reply, i){ 

        async.parallel([ 
         function(callback) { 
          var queryBook = Book.findOne(reply.bookEnd); 
          queryBook.exec(function callBack(err,bookEndFound) { 
           if (!err) { 
            reply.bookEnd = bookEndFound; 
            callback(); 
           }         
          }) 
         }, 
         function(callback) { 
          var queryUser = User.findOne(reply.user) 
          queryUser.exec(function callBack(err,userFound){ 
           if (!err) { 
            reply.user = userFound; 
            callback(); 
           } 

          }) 
         } 
        ], function(err){ 
         if (err) return next(err); 

         return res.json(200, reply); 
        }) 


       }) 
      }) 



     } else { 
      return res.json(401, {err:err}) 
     } 
    }) 
} 

ich die Asynchron-Bibliothek verwenden kann, aber Anregungen brauche

Danke Leute!

+0

können Sie einen Code ???? – vkstack

+0

@vkstack ja, zurück zu diesem so schnell wie möglich – Asso

+0

@vkstack aktualisiert – Asso

Antwort

1

Wie in den Kommentaren darauf hingewiesen, hat Waterline noch keine tiefe Bevölkerung, aber Sie können async.auto verwenden, um aus der Callback-Hölle herauszukommen. Der Trick besteht darin, die IDs aller Kinder, die Sie finden müssen, zu sammeln, sie mit einzelnen Abfragen zu finden und sie dann wieder den Eltern zuzuordnen. Der Code würde ungefähr wie folgt aussehen.

async.auto({ 

    // Get the askedAdvices 
    getAskedAdvices: function(cb) { 
    queryAskedAdvices.exec(cb); 
    }, 

    // Get the IDs of all child records we need to query. 
    // Note the dependence on the `getAskedAdvices` task 
    getChildIds: ['getAskedAdvices', function(cb, results) { 
    // Set up an object to hold all the child IDs 
    var childIds = {bookEndIds: [], userIds: []}; 
    // Loop through the retrieved askedAdvice objects 
    _.each(results.getAskedAdvices, function(askedAdvice) { 
     // Loop through the associated replayAdvice objects 
     _.each(askedAdvice.replayAdvices, function(replayAdvice) { 
     childIds.bookEndIds.push(replayAdvice.bookEnd); 
     childIds.userIds.push(replayAdvice.user); 
     }); 
    }); 
    // Get rid of duplicate IDs 
    childIds.bookEndIds = _.uniq(childIds.bookEndIds); 
    childIds.userIds = _.uniq(childIds.userIds); 
    // Return the list of IDs 
    return cb(null, childIds); 
    }], 

    // Get the associated book records. Note that this task 
    // relies on `getChildIds`, but will run in parallel with 
    // the `getUsers` task 
    getBookEnds: ['getChildIds', function(cb, results) { 
    Book.find({id: results.getChildIds.bookEndIds}).exec(cb); 
    }], 

    getUsers: ['getChildIds', function(cb, results) { 
    User.find({id: results.getChildIds.userIds}).exec(cb); 
    }] 

}, function allTasksDone(err, results) { 

    if (err) {return res.serverError(err); 

    // Index the books and users by ID for easier lookups 
    var books = _.indexBy(results.getBookEnds, 'id'); 
    var users = _.indexBy(results.getUsers, 'id'); 

    // Add the book and user objects back into the `replayAdvices` objects 
    _.each(results.getAskedAdvices, function(askedAdvice) { 
    _.each(askedAdvice.replayAdvices, function(replayAdvice) { 
     replayAdvice.bookEnd = books[replayAdvice.bookEnd]; 
     replayAdvice.user = users[replayAdvice.bookEnd]; 
    }); 
    }); 

}); 

Beachten Sie, dass dies von den integrierten Lodash- und Async-Instanzen von Sails ausgeht; Wenn Sie neuere Versionen dieser Pakete verwenden, hat sich die Verwendung von async.auto leicht geändert (die Argumente der Taskfunktion sind so getauscht, dass vor lautet).

+0

Vielen Dank! Endlich nicht wie async.auto funktioniert, greta Erklärung! – Asso

Verwandte Themen