Я уже вижу несколько ловушек, с которыми вы, как новички, столкнетесь в этом коде:
avait
ждет результатов, которые он получит, поскольку он получит Promisses
решить ее then
выполняет обещания асинхронно - функция, определенная как
async
всегда возвращает обещания
После минуты восторга, теперь async / awaitЯ стараюсь избегать его.Главным образом потому, что каждая функция, в которой я использую асинхронную функцию, также должна быть асинхронной, пока вы не используете then
, например, сделайте небольшой тест:
let test = async function() {
let x = await 11
return 1;
}
console.log(test()) //returns: Promise { <pending> }
Там нет ничего асинхронного, но добавление async / await
вызвалоmess.
Теперь исправления для вашего кода
const mariadb = require('mariadb');
// use local scope `let` instead global `var`
let test = async function(){
let conn = await mariadb.createConnection({
host: "localhost",
user: "dave",
connectionLimit: 5,
password: "!@#",
database: "db",
rowsAsArray: false
});
return conn.query("SELECT 1 as val") // no sense using `avait` because `test()` returns `promise`
}
test().then(function(rows) { console.log(rows)});
и без asnc.then
может вернуть обещание, и это может быть решено следующим then
mariadb.createConnection(...).then(conn => { // create connection
return conn.query("SELECT 1 as val") // make query
}).then(rows => { //get result
console.log(rows)
}).catch(err => console.error(err)) // get errors
Кстати: заинтересоваться построителем запросов, например knex.js.Это позволяет писать код независимо от ядра базы данных.
Обновление
Начнем с того, что Node основан на событиях.
Давайте рассмотрим пример получения данных из базы данных.В PHP / C ++ вы делаете запрос, ждете, получаете результат.И это поведение имитирует await
.(Ожидание появилось где-то рядом с версией 8)
Обычно код в узле работает так, что вы выполняете запрос, и узел создает новый поток.Старый запустить следующую инструкцию, в новом вы получите результаты.(Хорошо, я вру, но это легче объяснить).
Итак, вы должны обработать событие получения данных.А точнее promise
предоставления данных.По await
, .then ()
или callback (hell)
первое объяснение кода:
Вы пытаетесь вернуть ret
, но этот код сначала создает return ret
и после назначения.
await
«возвращает» данные, поэтому вы должны использовать let var_name = await asyncFunction()
Я предполагаю, что вы хотите это:
let getSomeDataFromDB = function(){
return mariadb.createConnection([skip]).then(conn => {
return conn.query("SELECT 1 as val")
})
}
let rows = await getSomeDataFromDB()
В этой функции вы возвращаетеобещаю, кто вернет обещание.И к await
эта цепочка обещаний разрешена.
Но вот "небольшая" ошибка в коде.Потому что вы подключаетесь, и вы нигде не прекращаете свое подключение.Поэтому лучше иметь глобальный объект соединения или использовать что-то вроде этого:
let getSomeDataFromDB = function(){
return new Promise(function(resolve, reject){
mariadb.createConnection([skip]).then(conn => {
conn.query("SELECT 1 as val")
.then(rows=>resolve(rows))
.catch(e=>reject(e))
.then(()=>conn.close())
}).catch(e => reject(e))
})
}
let rows = await getSomeDataFromDB()
И здесь вы обнаружите еще одну важную вещь: resolve
не прерывает выполнение кода.Несмотря на то, что данные возвращаются пользователю, вы все равно можете что-то сделать.
Или то же самое с await
let getSomeDataFromDB = async function(){
let conn = await reateConnection([skip])
let rows = await conn.query("SELECT 1 as val")
await conn.close();
return rows;
}
let rows = await getSomeDataFromDB()