繁体   English   中英

NodeJs util.promisify 不是函数

[英]NodeJs util.promisify is not a function

我正在尝试 promisify 一个 mysql 函数,但是当我运行它时,控制台显示此错误util.Promisify is not a function 这是我的代码:

 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); })

同样的错误如果var query = util.promisify(mysql.query);

我是新编程,但我正在努力学习。

util.promisify 是 Node 8.X 版本的一部分。 但是您仍然可以为旧版本的 Node.js 使用 polyfill。

一个 polyfill 可用于处理您将在其上运行应用程序的旧版本节点服务器。 它可以通过以下方式通过 npm 安装:

 npm install util.promisify

现在您可以在旧版本的 Node 上修补模块 utl

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

引自https://grizzlybit.info/blog/nodejs-util-promisify

除非您使用的是 Node.js 8.x,否则不会定义此函数, 那时它将被添加到核心Utilities库中。

由于util是一个核心的 Node.js 库,因此您不必安装它。 如果您使用的是 Node.js 6.x,那么请使用像Bluebird这样具有promisify函数的库。

其他人已经讨论过该解决方案,但这是此错误的另一个来源:

有一个 NPM 包es6-promisify也可以给出错误消息TypeError: promisify is not a function (这就是我问这个问题的原因。)

  • es6-promisify 5.0.0 版本需要const promisify = require("es6-promisify"); 然后你会使用result = promisify( ... );

  • 6.0.0 版本 API 有所变化,声明改为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 中,因此如果您可以更新节点,我会这样做。

以下示例应该适合您:

 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; }

此示例使用 Node.js 的标准 MySQL 模块。 util.promisify 是 Node.js 的内置实用程序。 使用节点 8。

代码被包装成一个异步函数。 在它的第一行中,回调函数“pool.getConnection”被转换为承诺并立即使用附加的“await”语句调用。 这将创建一个异步函数序列并返回一个值(一个连接)而不是一个函数或承诺。 下一行对 'conection.query' 执行相同的操作,但为了简单起见,将代码拆分为两个语句。 最后,该函数像任何同步函数一样返回查询结果。

如果你有webpack / babel设置,你可以使用babel-plugin-transform-util-promisify 它允许您在节点版本 < 8 中使用util.promisify 。如果您的目标节点版本 >= 8 但希望保持较低版本的向后兼容性,这也非常有用。

该插件转换以以下两种格式编写的代码:

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

import { promisify } from 'util';

您需要在.babelrc设置插件:

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

该插件将importrequire转换为节点版本 < 8 的函数声明。它会自动检测版本 >= 8 并在这些情况下使用本机util.promisify

披露我是 babel-plugin-transform-util-promisify 的作者和维护者

分享我的工作示例:

我将这个Promisified MySQL 中间件用于 Node.js

这是我的 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

您必须升级 node -v > 8.x

您必须使用 async 函数才能使用 await。

例子:

   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)
       }

我的问题是我一开始就没有安装util

所以, npm i util解决了我的问题

这是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) );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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