如何获取Minio中被promisify包装方法的参数列表?
封装Minio类方法自动填充参数的问题与解决
需求
- 封装Minio类的方法,调用时自动填充bucketName、region等参数,无需手动指定所有参数
实现思路
- 从Minio类原型获取所有方法并动态创建包装器
- 获取原方法参数名
- 自动添加预设参数后调用原方法
遇到的问题
Minio中部分方法(如bucketExists)被内置的promisify工具包装后,无法获取原方法的参数列表,导致自动填充参数逻辑失效
相关代码
Minio内置的promisify实现(minio/dist/main/helpers.js)
exports function promisify(fn){ return function(){ const args = [...arguments]; fn.apply(this, args); } }
Minio类及方法包装示例(minio/dist/main/minio.js)
class Minio{ bucketExists(bucketName){ return bucketName; } methodThatNotWrappedByPromisifyAndWorksFine(bucketName){ return bucketName; } } module.exports = Minio; Minio.prototype.bucketExists = (0,helpers.promisify)(Minio.prototype.bucketExists)
我的包装器代码
const proxyHandler = () => { return { apply: (target, thisArg, argumentsList) => { const funcParams = getMethodParamNames(target.source ? target.source.functionForWrap : target); const bucketNameIndex = funcParams.indexOf("bucketName"); const regionNameIndex = funcParams.indexOf("region"); if (bucketNameIndex >= 0) { argumentsList.splice(bucketNameIndex, 0, this.bucket.name); } if (regionNameIndex >= 0) { argumentsList.splice(regionNameIndex, 0, this.bucket.region); } try { return target.apply(this.minioClient, argumentsList); } catch (error) { logger.engine.error(`S3 '${this.bucket.name}' ${target} error: ${error.message}`, error.stack); } }, } } getMethods(this.minioClient).forEach(func => { this[func] = new Proxy(this.minioClient[func], proxyHandler()); })
最终解决方案
通过补丁Minio的promisify方法,为包装后的函数添加source属性保存原函数信息,这样后续就能通过该属性获取原方法的参数列表:
const MinioHelpers = require('minio/dist/main/helpers'); const origMinioPromisify = MinioHelpers.promisify; MinioHelpers.promisify = (functionForWrap) => { console.log("PATCHED!", functionForWrap); var fn = origMinioPromisify(functionForWrap); // 保存原函数相关信息,用于后续获取参数列表 fn.source = { functionForWrap, promisify: origMinioPromisify, } return fn } var Minio = require('minio');
内容的提问来源于stack exchange,提问作者TwistedMind
相关产品推荐
相关产品推荐

