xdenser / node-firebird-libfbclient

Firebird SQL binding
MIT License
82 stars 34 forks source link

promisify a member method #111

Closed sqllyw closed 3 years ago

sqllyw commented 3 years ago

Hi,

I am trying to promisify connection.query, code as follow but got error: UnhandledPromiseRejectionWarning: TypeError: Illegal invocation, any idea why? thanks

const fb = require("firebird");
const util = require('util')

const con = fb.createConnection();
con.connectSync("10.114.173.149://opt/firebird/examples/employee.fdb", 'sysdba', 'masterkey', '');

async function query_proc() {
    const query = util.promisify(con.query)
    let res = await query("select * from employee") //UnhandledPromiseRejectionWarning: TypeError: Illegal invocation
    return res
}

query_proc().then((res) => {
    console.log(res)
})
xdenser commented 3 years ago

IMHO because query is a method of connection object, read about "Using promisify() on class methods" in nodejs docs. Or just try to use util.promisify(con.query).bind(con)

sqllyw commented 3 years ago

thanks, bind(con) works! is there a way to promisify res.fetch? it has two callbacks

xdenser commented 3 years ago

Read NodeJS documentation I cannot write every method for you.

const fb = require("firebird");
// fb.binding.FBResult.prototype.fetch[util.promisify.custom] = function(numberOrAll)  { // try also this instead of next line - then it only need to be called once (not on each result)
res.fetch[util.promisify.custom] = function(numberOrAll)  {
  return new Promise((resolve, reject) => {
        let rows = [];
        this.fetch(numberOrAll, row => rows.push(row), (err, eof) => {
               if(err) return reject(err);
               resolve({
                 rows: rows,
                 eof: eof
              });
        });
  });
};
let pFetch = util.promisify(res.fetch).bind(res);

if you always return all rows you may just promisify fetch to have no arguments and resolve with just rows.