简体   繁体   中英

NodeJs util.promisify is not a function

I'm trying to promisify a mysql function but when I run it the console shows this error util.Promisify is not a function . This is my code:

 var util= require('util'); var mysql= require('mysql'); var conection=mysql.createConnection({ host:'localhost', user:'root', password:'616897', database:'proyect' }); var query = util.promisify(conection.query); query(data.valida_user).then((rows)=>{ console.log(rows); }).catch((error)=>{ console.log(error); })

The same error if var query = util.promisify(mysql.query);

I´m new programming but I'm trying to learn.

util.promisify is a part of Node 8.X version. But you can still have a polyfill for the older version of Node.

A polyfill is available to take care of the older version of node servers you'll be running your application on. It can be installed via npm in the following manner:

 npm install util.promisify

Now you can patch module utl on older versions of Node

 const util = require('util'); require('util.promisify').shim(); const fs = require('fs'); const readFileAsync = util.promisify(fs.readFile);

Quoted from https://grizzlybit.info/blog/nodejs-util-promisify

Unless you're using Node.js 8.x this function won't be defined, that's when it was added to the core Utilities library.

As util is a core Node.js library , you shouldn't have to install it. If you're using Node.js 6.x then use a library like Bluebird which has a promisify function.

Other people have spoken to the solution, but here is another source of this error:

There's a NPM package es6-promisify that can also give the error message TypeError: promisify is not a function . (That's why I got to this question.)

  • Version 5.0.0 of es6-promisifiy needed const promisify = require("es6-promisify"); then you'd use result = promisify( ... );

  • Version 6.0.0 had a change of API, and the declaration changed to const { promisify } = require("es6-promisify");

如果你愿意,你可以自己承诺: const promisify = f => (...args) => new Promise((a,b)=>f(...args, (err, res) => err ? b(err) : a(res)));

Util 包含在 Node 8.x 中,因此如果您可以更新节点,我会这样做。

The following example should work for you:

 async () => { const connection = await (util.promisify(pool.getConnection).bind(pool))(); const fn2 = util.promisify(connection.query).bind(connection); const rows = await fn2('SELECT col1, col2 FROM Users WHERE email = ?', [email]); connection.release(); return rows; }

This example uses the standard MySQL module for Node.js. And the util.promisify is the built-in utility of Node.js. Node 8 is used.

The code is wrapped into an async function. Within it on the first line the callback function 'pool.getConnection' is converted into promises and called instantly with the additional 'await' statement. This creates a sequence of the async function and returns a value (a connection) instead of a function or promises. The next line does the same for the 'conection.query', but splits the code into two statements for the sake of simplicity. Finally the function returns the result of the query like any synchronous function.

If you have a webpack / babel setup, you can use babel-plugin-transform-util-promisify . It allows you to use util.promisify in node versions < 8. Also very useful if you are targeting node versions >= 8 but want to keep backward compatibility for lower versions.

The plugin transforms code written in the following two formats:

const { promisify } = require('util');

and

import { promisify } from 'util';

You would need to setup the plugin in your .babelrc :

{
  "plugins": [
    "transform-util-promisify"
    ],
    "presets": [
      ["env", {
        "targets": {
          "node": "current"
        }
      }]
    ]
}

The plugin transforms import and require to a function declaration for node versions < 8. It automatically detects version >= 8 and uses native util.promisify in those cases.

Disclosure I'm author and maintainer of babel-plugin-transform-util-promisify

Share my working example:

I use this Promisified MySQL middleware for Node.js

here is my database.js

var mysql = require('mysql'); 

// node -v must > 8.x 
var util = require('util');


//  !!!!! for node version < 8.x only  !!!!!
// npm install util.promisify
//require('util.promisify').shim();
// -v < 8.x  has problem with async await so upgrade -v to v9.6.1 for this to work. 



// connection pool https://github.com/mysqljs/mysql   [1]
var pool = mysql.createPool({
  connectionLimit : process.env.mysql_connection_pool_Limit, // default:10
  host     : process.env.mysql_host,
  user     : process.env.mysql_user,
  password : process.env.mysql_password,
  database : process.env.mysql_database
})


// Ping database to check for common exception errors.
pool.getConnection((err, connection) => {
if (err) {
    if (err.code === 'PROTOCOL_CONNECTION_LOST') {
        console.error('Database connection was closed.')
    }
    if (err.code === 'ER_CON_COUNT_ERROR') {
        console.error('Database has too many connections.')
    }
    if (err.code === 'ECONNREFUSED') {
        console.error('Database connection was refused.')
    }
}

if (connection) connection.release()

 return
 })

// Promisify for Node.js async/await.
 pool.query = util.promisify(pool.query)



 module.exports = pool

You must upgrade node -v > 8.x

you must use async function to be able to use await.

example:

   var pool = require('./database')

  // node -v must > 8.x, --> async / await  
  router.get('/:template', async function(req, res, next) 
  {
      ...
    try {
         var _sql_rest_url = 'SELECT * FROM arcgis_viewer.rest_url WHERE id='+ _url_id;
         var rows = await pool.query(_sql_rest_url)

         _url  = rows[0].rest_url // first record, property name is 'rest_url'
         if (_center_lat   == null) {_center_lat = rows[0].center_lat  }
         if (_center_long  == null) {_center_long= rows[0].center_long }
         if (_center_zoom  == null) {_center_zoom= rows[0].center_zoom }          
         _place = rows[0].place


       } catch(err) {
                        throw new Error(err)
       }

My problem was that I had not installed util in the first place.

So, npm i util solved my issue

Here is an implementation of promisify:

 var promisify = function(fn) { return function(){ var args = [].slice.apply(arguments); return new Promise( function(resolve,reject){ fn.apply( null, args.concat([ function(){ var results = [].slice.apply(arguments); (results[0])//first argument of callback is error ? reject(results[0])//reject with error : resolve(results.slice(1,results.length))//resolve with result(s) } ]) ) } ); } }; //some object that has async functions using callbacks // and using 'this' as invoking object var callbackApi = { name:"callback api", age:22, asyncFunction:function(arg1,arg2,callback){ setTimeout( function(){callback(null,arg1,arg2,this.name,this.age);}.bind(this), 10 ) } } //my object that will use the api functions with promisify // and using 'this' as invoking object var myObject = { connection:"connection", doSomething:function(arg){ var asyncFnAsPromise = //make sure to bind asyncFunction to callbackApi promisify(callbackApi.asyncFunction.bind(callbackApi)); //return promise created with result promisified callback api return asyncFnAsPromise(this.connection,arg) } } myObject.doSomething(44) .then( resolve=>console.log("resolve:",resolve) );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM