2017-02-02 5 views
0

Я пытаюсь перепроектировать сценарий узла из библиотеки (исследовательский проект) для выполнения следующих задач последовательно:Использование NodeJS Promises с MySQL

1) Открыть и прочитать файл (например, «input.txt «). Для простоты предположим, что содержимое отформатирован запросов SQL)

2) Создание подключения к базе данных MySQL

3) Выполнение запросов (сконструированных из (1) - Предположим, запросы должным образом определены в файл)

4) Прекратить соединение с базой данных

Я хочу эти задачи должны быть выполнены в порядке (то есть, 1--4). У меня нет большого опыта использования обещаний (Bluebird). Вот отрывок кода у меня до сих пор:

//Read the input file 
function readFilePromise(){ 
    return new Promise(function(resolve, reject){ 
     var filePath = path.join(__dirname, filename); 
     //asynchronous read 
     fs.readFile(filePath, 'utf8', function (err, text){ 
      if (err) 
       reject(err); 
      else 
       resolve(text.split('\n')); 
     }); 
    }) 
} 

//create connection 
function createConnectionPromise(){ 
    return new Promise(function (resolve, reject){ 
     var connection = mysql.createConnection(connectionOptions);//global 
     connection.connect(function(err){ 
      if(err){ 
       console.log('Error connecting to Db'); 
       reject(err); 
      } 
      else{ 
       console.log('Connection established'); 
       resolve(connection); 
      } 
     }); 
    }) 
} 

//do transactions 
function doTransactionsPromise (data){ 
    return new Promise(function (resolve, reject){ 
     var connection = data[0]; 
     var lines  = data[1]; 
     var topPromises = []; 

     lines.forEach(function(sSQL){ 
      var p = new Promise(function(resolve,reject){ 
       console.log('Add: ' + sSQL); 
       makeTransaction(connection, sSQL); 
       return connection; 
      }); 
      topPromises.push(p); 
     }); 
     resolve(topPromises); 
    }); 
} 

//make transaction  
function makeTransaction(connection, sSQL){ 
    connection.beginTransaction(function(err){ 
     function treatErro(err, connection) { 
      console.log('Failed to insert data in the database . Undoing!'); 
      connection.rollback(); 
     } 

    function final() { 
     connection.commit(function(err) { 
      if(err) { 
       treatErro(err, connection); 
      } 
      else { 
       console.log('Added: ' + sSQL); 
       return connection; 
      } 
     }); 
    } 

    if(err) { 
     treatErro(err, connection); 
    } 
    else { 
     connection.query(sSQL, function (err, result) { 
      if(err) { 
       console.log(sSQL); 
       treatErro(err, connection); 
      } 
      else { 
       id = result.insertId; 
      } 
     }); 
     final(); 
    } 
    }); 
} 

Promise.all([createConnectionPromise(), readFilePromise()]) 
    .then(doTransactionsPromise) 
    .then(function(promises){ 
     Promise.all(promises) 
      .then(function(data){ 
       var connection = data[0]; 
       connection.end(); 
      }); 
    }) 
    .catch(function(error) { 
     console.log('Error occurred!', error); 
    }); 

Запросы выполняются нормально, но подключение к БД не прекращается. Любая помощь приветствуется.

PS: Я уверен, что код можно улучшить массово.

ответ

1

Возможная проблема, которую я вижу в вашем коде в функции doTransaction

function doTransactionsPromise (data){ 
    return new Promise(function (resolve, reject){ 
    var connection = data[0]; 
    var lines  = data[1]; 
    var topPromises = []; 

    lines.forEach(function(sSQL){ 
     var p = new Promise(function(resolve,reject){ 
      console.log('Add: ' + sSQL); 

      makeTransaction(connection, sSQL); 
      return connection; 
     }); 
     // P is never fullfilled. 
     //Either transfer the responsibility to full-fill the promise to makeTransaction 
     // or makeTransaction function should return the promise which is full-filled by itself. 

     topPromises.push(p); 
    }); 

    resolve(topPromises); 
}); 
} 
+0

спасибо за предложение. Любая идея, как это попробовать? – STiGMa

0

Я не проверял код, но следующий код должен делать

//Read the input file 
    function readFilePromise(){ 
     return new Promise(function(resolve, reject){ 
      var filePath = path.join(__dirname, filename); 
      //asynchronous read 
      fs.readFile(filePath, 'utf8', function (err, text){ 
       if (err) 
        reject(err); 
       else 
        resolve(text.split('\n')); 
      }); 
     }) 
    } 

    //create connection 
    function createConnectionPromise(){ 
     return new Promise(function (resolve, reject){ 
      var connection = mysql.createConnection(connectionOptions);//global 
      connection.connect(function(err){ 
       if(err){ 
        console.log('Error connecting to Db'); 
        reject(err); 
       } 
       else{ 
        console.log('Connection established'); 
        resolve(connection); 
       } 
      }); 
     }) 
    } 

    //do transactions 
    function doTransactionsPromise (data){ 



     var connection = data[0]; 
     var lines = data[1]; 
     var topPromises = []; 

     topPromise = lines.map(function(sSQL){ 

      return makeTransaction(connection, sSQL); 
     }); 

     return Promise.all(topPromises).then(function(){ 
       return connection; 
     },function(){ 
      return connection; 
     }); 


    } 

    //make transaction  
    function makeTransaction(connection, sSQL){ 
     return new Promise(resolve, reject, function(){ 
      connection.beginTransaction(function(err){ 

      function treatErro(err, connection) { 
       console.log('Failed to insert data in the database . Undoing!'); 
       connection.rollback(); 
       reject(connection); 

      } 

      function final() { 
       connection.commit(function(err) { 
        if(err) { 
         treatErro(err, connection); 
        } 
        else { 
         console.log('Added: ' + sSQL); 
         resolve(connection); 
         return connection; 
        } 
       }); 
      } 

      if(err) { 
       treatErro(err, connection); 
      } 
      else { 
       connection.query(sSQL, function (err, result) { 
        if(err) { 
         console.log(sSQL); 
         treatErro(err, connection); 
        } 
        else { 
         id = result.insertId; 
        } 
       }); 
       final(); 
      } 
      }); 

     }) 

    } 

    Promise.all([createConnectionPromise(), readFilePromise()]) 
     .then(doTransactionsPromise) 
     .then(function(connection){ 
      return connection.end(); 
     }) 
     .catch(function(error) { 
      console.log('Error occurred!', error); 
     }); 
Смежные вопросы