Как вы возвращаете информацию mongodb в браузер в обработчике маршрута hapi.js? - PullRequest
0 голосов
/ 05 мая 2018

Я только начинаю с hapi.js (^ 17.3.1) и mongodb (^ 3.0.7), а также с асинхронным кодом js.

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

начало dbInfo1 dbInfo2 dbInfoN конец

Я пробовал разные версии этого кода:

module.exports = {
    method: 'GET',
    handler: async function (request, reply) { 
        return await getRoutes();
    }       
}

async function getRoutes() {

    var s = "start";
    const mongo = require('mongodb').MongoClient;
    const mongoUrl = "mongodb://127.0.0.1:27017/";

    return // I'm returning this whole thing because hapi.js says it wants a promise. (500 error)
        await mongo.connect(mongoUrl)
        .then(function(client) {

            client.db("dbName").collection("collectionName")
            .find({})
            .forEach(function (record) {
                console.log(record.item);
                s += " | " + record.item;      
            });

            s + " end";  // But I've tried placing "return" here (500 error)

        });
        // I've also tried ".then(function(s) { return s + 'end' }) here but it seems to only have the same set of options/problems manifest.

        // I've also made it so that I place "return s + 'end'" here (displays "start end" with nothing in the middle).

}

Я пытался разместить оператор возврата в разных местах. Я либо получаю ошибку http 500 в консоли

Отладка: внутренняя, реализация, ошибка
Ошибка: метод-обработчик не возвратил значение, обещание или не выдал ошибку
dbInfo1
dbInfo2
dbInfoN

если я верну обещание или изнутри обещания, или получу

начало и конец

в браузере, если я вернусь извне обещание.

В любом случае оператор console.log выводит вывод dbInfos.

Я пробовал разные размещения, включения и пропуски асинхронных операций и жду с почти одинаковыми результатами. Я также попытался обернуть то, что возвращается внутри getRoutes, в явный Promise, используя «new Promise (...». В этом случае консоль регистрирует dbInfos, но браузер зависает.

Как мне дождаться этой функции "foreach" перед возвратом переменной s?

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

Наконец-то! Получил работу с этим кодом:

module.exports = {
    method: 'GET',
    handler: function (request, reply) { 
        return getRoutes();
    }
}

function getRoutes() {

    const mongo = require('mongodb').MongoClient;
    const mongoUrl = "mongodb://127.0.0.1:27017/";

    return mongo.connect(mongoUrl)
        .then(async function(client) {

            var s = "start";

            var documents = await 
                client.db("dbName").collection("collectionName")
                .find()
                .toArray();

            for (const doc of documents) 
                s += " | " + await doc.item;      

            return s + " end";

        });

}

Проблема заключалась в том, что я думал, что, поскольку «getRoutes» был помечен как «асинхронный», содержимое внутри «.then» также было асинхронным. Но мне действительно нужно было пометить «функцию (клиент)» как «асинхронный». Мне также нужно было прекратить использовать «forEach» и использовать более традиционную итерацию для коллекции.

Я на самом деле ранее помечал «function (client)» как «async», но это было без проб и ошибок, поэтому я никогда не использовал «await» должным образом. Я действительно не начинал понимать это, пока не прочитал этот блог Антона Лавренова.

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

0 голосов
/ 05 мая 2018

Без теста я могу сказать, что это неправильно:

return // I'm returning this whole thing because hapi.js says it wants a promise. (500 error)
    await mongo.connect(mongoUrl)
    .then(function(client) {

        client.db("dbName").collection("collectionName")
        .find({})
        .forEach(function (record) {
            console.log(record.item);
            s += " | " + record.item;      
        });

        s + " end";  // But I've tried placing "return" here (500 error)

    });

возврат анализируется как возврат;

return await mongo.connect(mongoUrl)
    .then(function(client) {

        client.db("dbName").collection("collectionName")
        .find({})
        .forEach(function (record) {
            console.log(record.item);
            s += " | " + record.item;      
        });

        s + " end";  // But I've tried placing "return" here (500 error)

    });

это правильный путь. Любой мусор предупредил бы вас об этом.

...