Asynchroniczność w bazie danych

0
let tabhelper = [];
router.route('/').get((req, res) => {
  Player.find()
    .then(players => {
      res.json(players);
      players.forEach(function (player) {
        Data.findOne({ nick: player.nick }, function (err, obj) {
          tabhelper.push(obj);
        })
      })
      console.log(tabhelper) // wydaje pusta tablice
    })
    .catch(err => res.status(400).json('Error: ' + err));
});

Witam, mam taki problem, zbieram wszystkich graczy z bazy "Player", później chcę znaleźć ich w bazie "Data" i zapisać do jakiejś tablicy, lecz jest tu problem z asynchroniczność..

0

Jest pusta tablica, bo console.log się wykonuje przed tym zagnieżdźonym kawałkiem kodu. Najlepiej jakbyś to przerobił na async/await. Wygląda na to, że wszystkie użyte tutaj technologie dobrze to wspierają.

A jeśli bym miał to zrobić w obrębie tego kodu to bym w najbardziej zagnieżdżonej funkcji postawił ifa, który by przesyłał wynik do res (no i wtedy trzeba użyć funkcji next z expressa).

1

A czy w Mongo nie ma możliwości dawania złożonych zapytań? Czyli czy musisz faktycznie iterować w JS po nazwach użytkowników, a potem za każdym razem dawać Data.findOne? Czy nie ma możliwości wyszukania od razu iluś rekordów zamiast tak ściubać? (może nie ma, nie wiem, z Mongo dawno korzystałem i pamiętam, że jakaś wybrakowana była ta baza. Ale może się coś zmieniło).

3

@LukeJL:

Szybkie proste konsolowe: 3 x to samo

let mongoClient = require('mongodb').MongoClient;
let url = "mongodb://localhost:27017";
let options = {useUnifiedTopology: true};

mongoClient.connect(url, options, (error, connection) => {
    if (error) throw error;

    let collection = connection.db('business').collection("employees");

    let cursor = collection.find({"address.country": "Poland"})
        .project({_id: 0})
        .limit(3);

    cursor.toArray((err, documents) => {
        if (err) {
            connection.close(err => {
                if (err) {
                    throw err;
                }
            });
            throw err;
        }

        documents.forEach(e => console.log(e));

        connection.close(err => {
            if (err) {
                throw err;
            }
        });
    })
});
let mongoClient = require('mongodb').MongoClient;
let url = "mongodb://localhost:27017";
let options = {useUnifiedTopology: true};

function getConnection(client, uri, opt) {

    return new Promise((resolve, reject) => {
        client.connect(uri, opt, (err, connection) => {
            if (err) {
                reject(err);
            } else {
                resolve(connection);
            }
        });
    })

}

function getDocuments(cursor) {

    return new Promise((resolve, reject) => {

        cursor.toArray((error, documents) => {
            if (error) {
                reject(error);
            } else {
                resolve(documents);
            }
        })
    });
}

getConnection(mongoClient, url, options)
    .then(connection => {
        let collection = connection.db('business').collection('employees');
        return collection.find({"address.country": "Poland"}).project({_id: 0}).limit(3);
    })
    .then(cursor => getDocuments(cursor))
    .then(array => array.forEach(e => console.log(e)))
    .catch(err => console.log(err));
let mongoClient = require('mongodb').MongoClient;
let url = "mongodb://localhost:27017";
let options = {useUnifiedTopology: true};


const getConnection = (client, uri, opt) => {
    return new Promise((resolve, reject) => {
        client.connect(uri, opt, (err, connection) => {
            if (err) {
                reject(err);
            } else {
                resolve(connection);
            }
        });
    });
};

const getDocuments = (query) => {

    return new Promise((resolve, reject) => {
        query.toArray((error, documents) => {
            if (error) {
                reject(error);
            } else {
                resolve(documents);
            }
        })
    });
}

const executeQuery = async (clientDb, uriDb, optDb) => {

    let connection;
    let documents;
    try {
        connection = await getConnection(clientDb, uriDb, optDb);
        let collection = connection.db('business').collection('employees');
        let query = collection.find({"address.country": "Poland"}).project({_id: 0}).limit(3);

        documents = await getDocuments(query);
    } catch (e) {
        console.log(e);
    } finally {
        connection.close(err => {
            if (err) throw err;
        });
    }

    documents.forEach(e => console.log(e));
}

executeQuery(mongoClient, url, options)
    .catch(e => console.log(e));
2

Jak chcesz wszystkie obiekty z kolekcji Data, to Data.find() zwraca wszystko.

1 użytkowników online, w tym zalogowanych: 0, gości: 1