[英]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.