Mam dwie kolekcje mangusty. Pierwszy zapisuje listę miejsc, a drugi odwiedza miejsca. Mój kod węzła przechodzi i próbuje uzyskać listę wizyt w każdym miejscu i zbudować ciąg, który wypisz jako JSON. Pierwsze zapytanie kończy się przed pierwszym uruchomieniem - czy istnieje sposób ich synchronicznego działania?Tworzenie zapytań mongoose.js synchronicznie
Odpowiedz
Nie ma natywnego synchronicznego api dla zapytań mongodów/mangusty (a twój nie chciałby, aby był praktyczny). Jak wspomina WiredPrarie, powinieneś połączyć zapytania, a drugi zaczyna się po pierwszym uruchomieniu i uruchomieniu wywołania zwrotnego. Oto przykład:
function findVisits(placesQuery,callback){
Places.find(placesQuery).exec(function(err,places){
if (err || !places.length){
console.log('there was a problem');
callback(err, null);
}else{
var visitQuery = ... //however you want to filter places
Visits.find(visitQuery).exec(function(err2,visits){
if (err2 || !visits.length){
console.log('there was a problem');
callback(err2,null);
}else{
callback(null, visits)
}
});
}
});
}
Naprawianie odpowiedzi: Nie ma sposób synchronicznej pracy w węźle. – gustavohenke
'Nie ma natywnego synchronicznego api dla zapytań mongodów/mangusty 'Złe wieści dla mnie, próbowałem uzyskać auto increment do pracy jak w przykładzie mongodb tutaj: http://docs.mongodb.org/manual/tutorial/create -an-auto-inkrementujące-pole/ale 'getNextSequence' nie może być asynchroniczne, ponieważ musi zwracać liczbę. Próba zastosowania tego automatycznego przyrostu w mangurze, ale musi znaleźć jakiś sposób wykonania funkcji synchronicznej: http: // stackoverflow.com/questions/28357965/mongoose-auto-increment – HMR
Nie zgadzam się z komentarzem "(i nie chciałbym, żeby jeden był praktyczny)". To jest dla każdego programisty mieć własne potrzeby. Na przykład. podczas debugowania w konsoli REPL w węźle, znacznie łatwiej byłoby przypisać wyniki linii po linii. Mogę wtedy użyć małej wtyczki, aby to zrobić. –
Jeśli używasz node.js następnie u powinny wykorzystywać https://github.com/caolan/async
kiedy trzeba pobierać dane z wielu kolekcjach trzeba wiele razy łańcucha zapytań.
Uczyni to Twój kod złożonym i trudnym do odczytania, bez modułowości. Użyj asynchroniczny stworzyć modułowość użyciu MongoDB i node.js
przykład kodu z mojego projektu:
var async = require('async');
var createGlobalGroup = function(socket, data) {
async.waterfall(
[
/**
* this function is required to pass data recieved from client
* @param {Function} callback To pass data recieved from client
*/
function(callback) {
callback(null, socket, data);
},
/**
* Step 1: Verify User
*/
verifyUser,
/**
* Step 2: Check User Access Rights And Roles
*/
checkUserAccessRightsAndRoles,
/**
* Step 3: Create Project
*/
createNewGlobalGroup], function(err, result) {
/**
* function to be called when all functions in async array has been called
*/
console.log('project created ....')
});
}
verifyUser = function(socket, data, callback) {
//do your query
/**
* call next function in series
* provide sufficient input to next function
*/
callback(null, socket, data, {
"isValidUser": true,
});
}
checkUserAccessRightsAndRoles = function(socket, data, asyncObj, callback) {
//do your query
if(condition) {
callback(null, socket, data, {
roles: result,
"isValidUser": asyncObj.isValidUser,
"userId": asyncObj.userId,
});
} else {
//no call back
}
}
var createNewGlobalGroup = function(socket, data, asyncObj, callback) {
//wanna stop then no callback
}
Oto alternatywna metoda wytwarzania pseudo synchronicznych żądań za pomocą MongooseJS. Chodzi o to, aby utworzyć kolejkę zapytań, które należy wykonać. Następnie utwórz funkcję, która jest wywoływana rekurencyjnie, dopóki kolejka nie zostanie wyczerpana. Po wyczerpaniu kolejki rekursja zatrzymuje się, a odpowiedź jest wysyłana z powrotem do pierwotnego żądania. Używam Express Routes, więc cały ten kod jest zamknięty w mojej procedurze obsługi trasy. W tym przypadku HTTP POST.
var express = require('express');
var router = express.Router();
//POST /auth/create
router.post('/create', function(req, res) {
var queue = [
{"schema": require('..\\models\\people.js'), "query": {username: req.body.username}},
{"schema": require('..\\models\\members.js'), "query": {username: req.body.username}}
],
retData = [];
var curTask = 0.
function recurse()
{
if(curTask < queue.length){
var task = queue[curTask];
task.schema.findOne(task.query, function(err, data){
retData.push(err || data);
curTask++;
recurse();
})
}else{
res.json(retData);
}
}
recurse();
});
module.exports = router;
Do synchronizacji Użyłem obietnicy es6.
var Promise = require('es6-promise').Promise
, mongoose = require('mongoose')
, Schema = mongoose.Schema;
// define schemas and models.
var placeSchema = new Schema({
name: { type: String },
memo: { type: String }
})
, Places = mongoose.model('place', placeSchema)
, visitSchema = new Schema({
placeName: { type: String }, // foreign key for place.
visitor: { type: String },
comment: { type: String }
})
, Visits = mongoose.model('visit', visitSchema);
// query for visits by visitor and place.
function findVisitsWithPlace(visitor, place) {
return new Promise(function (resolve, reject) {
Visits.find({
visitor: visitor,
placeName: place.name
}, function (error, visits) {
if (error) {
reject(error);
return;
}
// build a result object you want.
//()
resolve({
place: place,
visits: visits
});
});
});
}
// functions for node route.
module.exports = {
// - access to "GET /placevisits/?visitor=Visitor-1".
get: function (request, response) {
var visitor = request.query.visitor;
// - to get the places...
Places.find({}, function (error, places) {
Promise.all(places.map(function (place) {
// - run the child queries with parent object...
return findVisitsWithPlace(visitor, place);
})).then(function (placeAndVisits) {
// - and get result.
// placeAndVisits have still contain visits empty.
// exclude them.
var result = [];
placeAndVisits.forEach(function (placeandvisit) {
if (placeandvisit.visits.length != 0) {
result.push(placeandvisit);
}
});
response.json(result);
});
});
}
};
i JSON podąża za mną.
[
{
"place": {
"_id": "564e58a1dbed862155771d46",
"name": "Place-A",
"memo": "A memo for Place A."
},
"visits": [
{
"_id": "564e58cedbed862155771d49",
"placeName": "Place-A",
"visitor": "Visitor-1",
"comment": "A comment for Place A by Visitor-1"
},
{
"_id": "564e58dcdbed862155771d4a",
"placeName": "Place-A",
"visitor": "Visitor-1",
"comment": "2nd visit. Again comment for Place A by Visitor-1"
}
]
},
{
"place": {
"_id": "564e58afdbed862155771d47",
"name": "Place-B",
"memo": "A memo for Place B."
},
"visits": [
{
"_id": "564e58ebdbed862155771d4c",
"placeName": "Place-B",
"visitor": "Visitor-1",
"comment": "A comment for Place B by Visitor-1"
}
]
}
]
Dziś mangusta wspiera obietnice, więc możesz .then()
swoje pytania. Na przykład:
app.get(function (req, res, next) {
Users.findOne({
username: req.body.username,
password: req.body.password,
}).then(user => {
if (!user) {
res.json({success: false, message: "Username or password incorrect."});
return;
}
return Notifications.find({
user: user._id
}).then(notifications => {
res.json({success: true, notifications});
});
).catch(error => {
//console.error(error);
//res.json({success: false, error: error.message});
next(error);
});
});
Jeśli używasz 8.x Node można wykorzystać asynchroniczny/Oczekujcie: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
czekają operator wstrzymuje wykonanie funkcji asynchronicznym aż obietnica jest rozwiązany i zwraca wartość. W ten sposób Twój kod będzie wyglądać bardziej synchronicznie:
const query1 = MyModel.find({ name: /john/i }, null, { skip: 10 });
const result1 = await query1.exec();
const query2 = MyModel.find({ name: /john/i }, null, { skip: 100 });
const result2 = await query2.exec();
Zapytania będą wykonywane kolejno.
- 1. Mongoose.js: jak zaimplementować tworzenie lub aktualizację?
- 2. Tworzenie zapytań dynamicznych i bezpiecznych
- 3. Wiosenne dane JPA: tworzenie zapytań dotyczących specyfikacji zapytań
- 4. Tworzenie zapytań dopasowanie do aktualnej daty
- 5. MySQL. Tworzenie indeksu dla zapytań "OR"
- 6. Uruchom GC.Collect synchronicznie
- 7. Odliczanie Socket.io synchronicznie?
- 8. Mongoose.js pochłania błędy w zaproszeniu zwrotnym?
- 9. Mongoose.js: Atomowa aktualizacja właściwości zagnieżdżonych?
- 10. Mongoose.js: remove collection or DB
- 11. Ładowanie obrazu synchronicznie z Glide
- 12. Zdarzenie niestandardowe wyzwalacza jQuery synchronicznie?
- 13. Jak wyświetlić plan wykonania zapytania mongoose.js
- 14. Śledzenie zmian w polach za pomocą mongoose.js
- 15. jQuery: Tworzenie jednoczesnych zapytań ajaxowych, czy to możliwe?
- 16. Optymalny sposób na tworzenie długich zapytań SQL insert z PDO
- 17. Tworzenie zapytań generycznych w SQLite-net C# za pomocą SQLiteAsyncConnection
- 18. optymalizacji zapytań MySQL - wewnętrzne zapytań
- 19. Sposób wykonywania poleceń powłoki synchronicznie w PHP
- 20. Jak mogę uzyskać dostęp do indexedDB synchronicznie?
- 21. czytano wiersze z pliku synchronicznie w node.js
- 22. Meteor.call ("function", arg) nie występuje synchronicznie
- 23. Wykonaj polecenie powłoki synchronicznie z Elixir/Erlang
- 24. Ładowanie obrazów synchronicznie za pomocą javascript
- 25. Przerysuj okienko sterowania Synchronicznie (z metodą blokowania)
- 26. Websocket: czy dane serwera są wysyłane synchronicznie?
- 27. W takim przypadku TaskCompletionSource.SetResult() uruchamiać kontynuację synchronicznie?
- 28. NodeJS gm pobieranie rozmiaru obrazu synchronicznie
- 29. Mongoose.js: W jaki sposób zaimplementować strukturę drzewa przez populację
- 30. grupy przez miesiąc i rok za pomocą mongoose.js
Dlaczego nie rozpocząć drugiej kwerendy po pierwszym zakończeniu, jeśli zamówienie ma znaczenie (chociaż nie rozumiem, dlaczego zamówienie ma znaczenie, o ile kod budowania JSON czeka na ich zakończenie?) – WiredPrairie