簡體   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