[英]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);
除非您使用的是 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"
}
}]
]
}
该插件将import
和require
转换为节点版本 < 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.