@Vasek1209

Как сделать через цепочку промисов последовательное выполнение операций в SQLite в node js?

У меня есть скрипт, который по шагам должен делать несколько асинхронных операций — сначала парсить несколько страниц, потом сгружать всё это в базу, потом отправлять что-то в Телеграм-бот. У меня всё работало нормально через setTimeout, сейчас переделываю на цепочку промисов через then, но на этапе обращений в SQLite что-то пошло не так.

Вот мой код, я его упростил и удалил лишнее.

export default (async function () {

    const parse = async function (url) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log(0);
                resolve();
            }, 1000);
        })
    }
    
    await parse('https://...').then((data) => {
        return data;
    }).then(() => {
        return new Promise((resolve, reject) => {
            try {
                const db = new sqlite3.Database('./db.db');
    
                db.serialize(() => {
                    db.all("SELECT * FROM table ORDER BY id;", (err, rows) => {
                        console.log(1) // !
                    });

                    db.close();

                    console.log(2) // !
                    resolve();
                })
            } catch (error) {
                console.log(error)
                reject();
            }
        })
    }).then(() => {
        console.log(3) // !
    })
})();


Нужно чтобы выводилось в консоль 0 1 2 3, но сейчас выводится 0 2 3 1. Как сделать, чтобы выполнение ждало строчку с SQL-запросом?

Вроде бы всё просто, но как-то не работает. Пробовал вставлять async перед функцией в промисе и await перед обращениями в базу, но не помогло. Помогите, пожалуйста, я нуб.
  • Вопрос задан
  • 106 просмотров
Решения вопроса 1
szQocks
@szQocks
Как-то так мб

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

const connect_and_query = () => {
    const db = new sqlite3.Database('./db.db');
    
    return new Promise((resolve, reject) => {
      db.serialize(() => {
        db.all("SELECT * FROM table ORDER BY id;", (err, rows) => {
          if(err){
            reject(err)
          } else {
            resolve(rows)
          }
        });
      })
    }).finally(() => {
      db.close();
    });
} 


const f = () => Promise.all([sleep(1000),connect_and_query()]);

export default f;


пример:
f().then(res => console.log(res));
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
mayton2019
@mayton2019
Bigdata Engineer
Асинхронное программирование не обязано соотвествовать структурному. Ты предполагаешь
что код исполняется сверху-вниз как в Pascal. Но он выполняется в соответствии с тем как
срабатывают отложенные функции. Вот когда SELECT вернет данные - тогда и твой чек-поинт "1" будет
напечатан.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы