Синхронизация обещаний для инициализации базы данных MongoDB - PullRequest
0 голосов
/ 05 декабря 2018

Я новичок в веб-разработке, но у меня есть те вопросы, касающиеся MongoDB и драйвера Nodejs, с учетом этого кода:

let MongoClient = require('mongodb').MongoClient;
const url = MY_URL;
const dbConnected = MongoClient.connect(url);
let dbInit =  function (){
    dbConnected.then(
        (client) => {
            let db = client.db('DB_NAME');
            db.dropDatabase()
                .then( () => {})
                .catch( err => { throw err;})
            return client;
        }
    )
    .then(
        (client) =>{
            let db = client.db('knodels');
            db.collection('Users').insertMany([
                //data
            ])
            .then( () => {})
            .catch( err => { throw err;})
            return client;
       }
    )
    .then(
        (client) =>{            
            client.close();
        }
    )
    .catch((err) => {throw err;})
}

Я хочу добиться этих вещей:

  1. отбросить базу данных
  2. создать базу данных после удаления и заполнить ее
  3. закрыть соединение

Все эти цели достигаются, когда я запускаю функцию, но я думаю, что естьчто-то не так с кодом:

  • при запуске dbInit() некоторые UnhandledPromiseRejectionWarning выбрасываются
  • определенно есть что-то нехорошее с синхронизацией этих обещаний, которые должны быть асинхронными Iугадайте
  • отлов ошибок делается только в конце или для всех обещаний?
  • обещание закрыть клиентское соединение

1 Ответ

0 голосов
/ 05 декабря 2018

Позволяет назвать некоторые сегменты кода,

let dbInit =  function (){
dbConnected.then(
    (client) => {
        //////////////////////TASK 1/////////////////////
        let db = client.db('DB_NAME');
        db.dropDatabase()
            .then( () => {})
            .catch( err => { throw err;})
        return client;
       //////////////////////TASK 1/////////////////////
    }
)
.then(
    (client) =>{
        //////////////////////TASK 2/////////////////////
        let db = client.db('knodels');
        db.collection('Users').insertMany([
            //data
        ])
        .then( () => {})
        .catch( err => { throw err;})
        return client;
        //////////////////////TASK 2/////////////////////
   }
)
.then(
    (client) =>{            
        client.close();
    }
)
.catch((err) => {throw err;})
}

В цепочке обещаний, Как и в предыдущем примере, блок «then» будет выполняться после того, как прецедент будет разрешен.Это означает, что блок then, содержащий TASK 2, будет выполнен только после завершения TASK 1.

Но поскольку вы не возвращаете обещание из TASK 1, вместо этого возвращая истинное значение (переменная клиент), и поскольку истинные значения рассматриваются как разрешение обещаний.Он может / мог бы начать выполнение db.collection('Users').insertMany... даже до того, как удаление завершено.

Аналогичная вещь применима к следующему блоку then, где client.close будет вызываться до завершения вставки.

Таким образом, вместо того, чтобы возвращать клиента повсюду, верните операцию db, ее обещание, и это сделает цепочку последовательной.

Также вам не нужна такая вложенная цепочка с ловушками при каждом обещании, что-то вроде

let connection = null;
dbConnected.then((client) => {
  connection = client;  
  const db = client.db('DB_NAME');
  return db.dropDatabase()
}).then(() => {
  // Perform insert and return a promise//
}).then(() => {
  return connection.close();
}).catch((err) => {
   // handle error //
})

должен делать эту работу !!

...