Проблемы с Node.js и oracledb

У меня проблема со скриптом node.js на работе (кстати, я новичок в узле вообще). Когда я запускаю цикл forEach, кажется, что он может работать асинхронно, и поэтому проблема не возникает. Однако, когда я просматривал документацию по пакету, я ничего не нашел о синхронном выполнении SQL. Заранее спасибо за помощь!

function getLastLoginAndProviderType(jsonObj, connection){
console.log(jsonObj);
jsonObj.forEach(obj => {
console.log("Processing: " + obj["email"]);
//obj["email"], obj["first"], obj["last"], obj["eid"], obj["role"] 

var sql = "select LAST_LOGGED_IN_TIME from EINV_OWNER.CONTACT where EMAIL_ADDRESS='" + obj['email'] + "'";

connection.execute(
  sql, {}, { maxRows: 15 },
  function(err, result) {
    if (err) {
      console.error("Query Error: " + err.message);
    } else {
      console.log("Number of rows returned: " + result.rows.length);

      obj["lastLoggedIn"] = "null";
      obj["supplierOrProvider"] = "null";
    }
  });
});

Когда скрипт запустится, я ожидаю увидеть что-то вроде:

Processing: [email protected]
Number of rows returned: XX
Processing: [email protected]
Number of rows returned: XX
...
Processing: [email protected]
Number of rows returned: XX

Однако в итоге я получаю:

Processing: [email protected]
Processing: [email protected]
Processing: [email protected]
...
Processing: [email protected]
Query Error: NJS-003: invalid connection
Query Error: NJS-003: invalid connection
Query Error: NJS-003: invalid connection
...
Query Error: NJS-003: invalid connection

Любые идеи? Спасибо!


person jhammond    schedule 05.10.2018    source источник


Ответы (1)


Краткий обзор основных опций:

Обратные вызовы

используйте такой пакет, как https://github.com/caolan/async, чтобы легко управлять циклом обратных вызовов for . (есть другие пакеты)

forEach не ждет завершения вашего обратного вызова, поэтому все они выполняются одновременно. Вы также можете управлять своим собственным циклом for, используя обратный вызов с итератором, который останавливается при достижении максимального итератора.

Но вы также можете использовать:

require('util').promisify для преобразования функции обратного вызова в стиле node.js

myFn(foo,bar,<function(err,data){}>) 

к обещанию, которое затем вы можете сделать следующее:

Обещания

Разрешить обещания одно за другим (т.е. последовательно)?

Асинхронный/ожидание

Или то, что вы, вероятно, хотели бы...

async function myFunction(){
  for(i=0;i<jsonObj.length;i++){
    try{
      let result = await connection.execute(sql, {}, { maxRows: 15 })
      console.log("Number of rows returned: " + result.rows.length);
      obj["lastLoggedIn"] = "null";
      obj["supplierOrProvider"] = "null";
    }catch(e){
      console.error("Query Error: " + err.message);
    }
  }
}
person Cody G    schedule 05.10.2018
comment
Большое спасибо за быстрый ответ! У меня есть один дополнительный вопрос, в вашем последнем примере Async/Await, как мне затем использовать мою функцию обратного вызова, которая у меня есть в моем вызове выполнения? - person jhammond; 05.10.2018
comment
Я также получаю сообщение об ошибке после выполнения npm install utils, где написано TypeError: require(...).promisify не является функцией, большое спасибо!!!! - person jhammond; 05.10.2018
comment
Извините, это require('util'), а не utils - person Cody G; 05.10.2018
comment
На самом деле похоже, что oracledb поддерживает его из коробки. - person Cody G; 05.10.2018
comment
Спасибо, приятель. Ты великолепен! - person jhammond; 05.10.2018
comment
@jhammond, поскольку ответ решил вашу проблему, пожалуйста, примите его (ответы отнимают у респондентов ценное время). - person desertnaut; 22.01.2019