UNPKG

magic-oopjs

Version:

新增了 多线程的异常日志输出

1,238 lines (1,066 loc) 74.9 kB
const { getDataType, objectDeepCompare } = require("./utils/function"); const { isFunction, validate, isAsyncFunction, isArray, isObject } = getDataType(); const Joi = require('@hapi/joi'); const colors = require("colors"); const { Worker, MessageChannel, MessagePort, isMainThread, parentPort } = require('worker_threads'); var errorMsg = ""; //判断两个对象是否相等 function _deepCompare(x, y) { var i, l, leftChain, rightChain; function compare2Objects(x, y) { var p; // remember that NaN === NaN returns false // and isNaN(undefined) returns true if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') { return true; } // Compare primitives and functions. // Check if both arguments link to the same object. // Especially useful on the step where we compare prototypes if (x === y) { return true; } // Works in case when functions are created in constructor. // Comparing dates is a common scenario. Another built-ins? // We can even handle functions passed across iframes if ((typeof x === 'function' && typeof y === 'function') || (x instanceof Date && y instanceof Date) || (x instanceof RegExp && y instanceof RegExp) || (x instanceof String && y instanceof String) || (x instanceof Number && y instanceof Number)) { return x.toString() === y.toString(); } // At last checking prototypes as good as we can if (!(x instanceof Object && y instanceof Object)) { return false; } if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) { return false; } if (x.constructor !== y.constructor) { return false; } if (x.prototype !== y.prototype) { return false; } // Check for infinitive linking loops if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) { return false; } // Quick checking of one object being a subset of another. // todo: cache the structure of arguments[0] for performance for (p in y) { if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { return false; } else if (typeof y[p] !== typeof x[p]) { return false; } } for (p in x) { if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { return false; } else if (typeof y[p] !== typeof x[p]) { return false; } switch (typeof (x[p])) { case 'object': case 'function': leftChain.push(x); rightChain.push(y); if (!compare2Objects(x[p], y[p])) { return false; } leftChain.pop(); rightChain.pop(); break; default: if (x[p] !== y[p]) { return false; } break; } } return true; } if (arguments.length < 1) { return true; //Die silently? Don't know how to handle such case, please help... // throw "Need two or more arguments to compare"; } for (i = 1, l = arguments.length; i < l; i++) { leftChain = []; //Todo: this can be cached rightChain = []; if (!compare2Objects(arguments[0], arguments[i])) { return false; } } return true; } // 检测对象内的$inner 属性, 该属性为保留属性 function _inner_checkinner(target) { if (target && !target.$inner) { target.$inner = { //$limit:new Map(),// 属性的限制数据格式 $methodsValidate: { $returns: new Map(), $params: new Map(), $desc: new Map(), }, $className: null,// 类名 $constructor: null,// 构造方法, $isHandleConstructor: false,// 标致是否执行了构造方法 ,如果未定义构造方法,则这里将不会为true $parentObj: null,// 父类对象 } } if (target && !target.super) { target.super = {} } if (target && !target.$parentInner) { target.$parentInner = {} } // 提供对外访问内部属性的方法 target.$getInner = () => { return target.$inner; } // 提供对外访问内部属性的方法 target.$getParentInner = () => { return target.$parentInner; } // 提供对外访问内部属性的方法 target.$setHandleConstructor = () => { target.$inner.$isHandleConstructor = true; } // 设置父类的对外构造方法 target.$setParentsConstuctor = (fun) => { target.super['constructor'] = fun; } // 读取父类对象 target.$getParentObj = () => { return target.$inner.$parentObj; } } // 检测类内的$inner 属性, 该属性为保留属性 function _inner_checkClssinner(target) { if (target && target.prototype && !target.prototype.$inner) { target.prototype.$inner = {} } if (target && target.prototype && !target.prototype.super) { target.prototype.super = {} } if (target && target.prototype && !target.prototype.$parentInner) { target.prototype.$parentInner = {} } } // 检测对象内的保留属性或方法 返回false 说明 不是内部保留属性,可用业务 /** * $inner 存放内部装饰修饰的一系列数据 * $parentInner 针对继承, 存放上一级父类的的保留数据 * super 针对继承, 存放上一级父类的在子类中也定义的属性或者方法 */ function _inner_checkinner_keywords(attr) { if (!attr) { return false; } let inner_attr = new Set(["$inner", "$parentInner", "super", 'constructor', "getter", "setter"]); return inner_attr.has(attr); } // 兼容读取schame function _inner_get_schame(paramsSchema) { if (!paramsSchema) { return null; } let schema = null; if (paramsSchema.validate && isFunction(paramsSchema.validate)) { schema = paramsSchema; } else { schema = Joi.object(paramsSchema); } if (schema == null) { throw new Error(`schame 校验对象构建失败`); } return schema } // schame 异常信息读取 function _inner_joi_error(error) { if (!error) { return; } let err = ""; if (error.details && error.details.length >= 0) { for (let e of error.details) { if (!e) { continue; } err += e.message + "、" } } return err; } // 检测传入的params的合法性 callType 为Params 或者 Returns 表示数据检测的类型时 调用检测还是 返回结果检测 function _inner_check_params(paramsSchema, params, className, key, callType = "Params") { var errorMsg = ""; if (paramsSchema) { if (callType == 'Params') { //console.log(paramsSchema,params) // if (!isArray(paramsSchema) || (!isArray(params))) { // errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:校验规则或者待校验参数必须是arguments 数组` // throw new Error(errorMsg); // } if (paramsSchema.length != params.length) { errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:校验规则规定的参数个数为${paramsSchema.length},但是实际传入的参数个数为${params.length}` throw new Error(errorMsg); } // 遍历校验参数 let i = 0; for (; i < paramsSchema.length; i++) { if (paramsSchema[i].toString() == Any.toString()) { continue; } // 这里处理params 不是对象情况 if (!isObject(params[i])) { if (paramsSchema[i] && paramsSchema[i].validate && isFunction(paramsSchema[i].validate)) { // console.log(paramsSchema[i].validate, params[i], '4444'); let { error } = paramsSchema[i].validate(params[i]); if (error) { let err = _inner_joi_error(error); errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数数组第${i}参数,校验异常,异常信息:${err}` throw new Error(errorMsg); } continue; } else { errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数数组第${i}参数,校验异常,异常信息:需要传入一个对象,因为在${callType}参数校验时,第${i}参数要求传入一个对象` throw new Error(errorMsg); } } let schema = _inner_get_schame(paramsSchema[i]); if (schema == null) { errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:schame 校验对象构建失败` throw new Error(errorMsg); } let { error } = schema.validate(params[i]); if (error) { let err = _inner_joi_error(error); errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数数组第${i}参数,校验异常,异常信息:${err}` throw new Error(errorMsg); } } } else if (callType == 'Returns') { // 这里处理params 不是对象情况 if (!isObject(params) && !isArray(params)) { if (paramsSchema && paramsSchema.validate) { let { error } = paramsSchema.validate(params); if (error) { let err = _inner_joi_error(error); //let err = validateResult && validateResult.error && validateResult.error.ValidationError?validateResult.error.ValidationError:"" errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:${err}` throw new Error(errorMsg); } return; } } // 这种情况说明是返回的数据是数组, 规则是不是数组,是使用Joi.array() 的规则 if (isArray(params) && !isArray(paramsSchema)) { // 这里直接校验 let schema = _inner_get_schame(paramsSchema); if (schema == null) { errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:schame 校验对象构建失败` throw new Error(errorMsg); } let { error } = schema.validate(params); if (error) { let err = _inner_joi_error(error); errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:${err}` throw new Error(errorMsg); } return; } if (isArray(paramsSchema) && !isArray(params)) { errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:${callType}参数要求是数组,但实际调用时传入的参数不是数组` throw new Error(errorMsg); } if (isArray(params)) { if (params.length != paramsSchema.length) { errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:${callType}参数要求是数组,但实际调用时传入的数据长度不一致` throw new Error(errorMsg); } for (let i = 0; i < params.length; i++) { if (!params[i] || !paramsSchema[i]) { errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:${callType}参数数组的第${i}个参数和传进来的参数有一个为null或者undefined` throw new Error(errorMsg); } if (paramsSchema[i].toString() == Any.toString()) { continue; } // 这里处理params 不是对象情况 if (!isObject(params[i])) { if (paramsSchema[i] && paramsSchema[i].validate && isFunction(paramsSchema[i].validate)) { // console.log(paramsSchema[i].validate, params[i], '4444'); let { error } = paramsSchema[i].validate(params[i]); if (error) { let err = _inner_joi_error(error); errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数数组第${i}参数,校验异常,异常信息:${err}` throw new Error(errorMsg); } continue; } else { errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数数组第${i}参数,校验异常,异常信息:需要返回一个对象,因为在${callType}参数校验时,第${i}参数要求返回一个对象` throw new Error(errorMsg); } } if (!isObject(paramsSchema[i]) && paramsSchema[i] != null) { errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:${callType}参数数组的第${i}个参数必须要求为一个合法对象,但实际的值为${paramsSchema[i]}` throw new Error(errorMsg); } if (!isObject(params[i])) { errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:传入参数数组的第${i}个元素必须要求为一个合法对象,但实际的值为${params[i]}` throw new Error(errorMsg); } let schema = _inner_get_schame(paramsSchema[i]); if (schema == null) { errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:schame 校验对象构建失败` throw new Error(errorMsg); } let { error } = schema.validate(params[i]); if (error) { let err = _inner_joi_error(error); errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数数组第${i}参数,校验异常,异常信息:${err}` throw new Error(errorMsg); } } } else { if (paramsSchema.toString() == Any.toString()) { return; } let schema = _inner_get_schame(paramsSchema); if (schema == null) { errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:schame 校验对象构建失败` throw new Error(errorMsg); } //console.log("pramas 检测 ", isArray(params), params); let { error } = schema.validate(params); if (error) { //console.log(error.details) let err = _inner_joi_error(error); //let err = validateResult && validateResult.error && validateResult.error.ValidationError?validateResult.error.ValidationError:"" errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:${err}` throw new Error(errorMsg); } } } else { errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,调用类型检测失败,${callType} 为未支持调用类型` throw new Error(errorMsg); } } // else { // errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,${callType} 参数校验异常,异常信息:paramsSchema ` // throw new Error(errorMsg); // } } // 通用getter 控制代理 function _getter(o, className, target, key, receiver, callPosition = "outer") { _inner_checkinner(target); if (callPosition == 'outer') { if (_inner_checkinner_keywords(key)) { errorMsg = `Factory getter 异常:类${className}的${key}属性或者方法 为内部保留方法/属性,不可直接访问` throw new Error(errorMsg); } } //console.log(o[key],key) if ((o[key] === undefined) || (o[key] === "undefined")) { errorMsg = `Factory getter 异常:类${className}的${key}属性或者方法 可能不存在` throw new Error(errorMsg); } // 访问权限控制 if (isFunction(o[key])) { if (callPosition == 'outer') { if (target.$inner.PrivateMethods) { if (target.$inner.PrivateMethods.has(key)) { errorMsg = `Factory getter 异常:类${className}的${key}为私有方法,不可外部访问` throw new Error(errorMsg); } } if (target.$inner.ProtectedMethods) { if (target.$inner.ProtectedMethods.has(key)) { errorMsg = `Factory getter 异常:类${className}的${key}为保护方法,不可外部访问` throw new Error(errorMsg); } } } //判断是异步函数还是同步 return function () { var _this = this; let params = arguments; //检测传入的parmas是否是正确的 if (target.$inner.$methodsValidate.$params.has(key)) { let paramsSchema = target.$inner.$methodsValidate.$params.get(key); //console.log(paramsSchema, arguments); _inner_check_params(paramsSchema, params, className, key); } // 检测方法返回的结果 function checkReturns(key, value) { let paramsSchema = target.$inner.$methodsValidate.$returns.get(key); _inner_check_params(paramsSchema, value, className, key, "Returns") } // 检测是是否是多线程运行 if (target.$inner.ThreadMethods && target.$inner.ThreadMethods.get(key)) { //console.log(`方法${key}是多线程方法。。。`); // 读取方法代码 let funcstr = o[key].toString() //console.log(funcstr); let threadConfig = target.$inner.ThreadMethods.get(key); if (threadConfig && threadConfig.logging) { console.log(`方法${key}在线程中执行`.cyan) } // 异步方法 if (funcstr.indexOf("_regenerator[\"default\"].async") != -1) { return new Promise((resolve, reject) => { try { const subChannel = new MessageChannel(); subChannel.port2.on('message', (value) => { //console.log('主线程的port2 接收到:', value); checkReturns(key, value) resolve(value) }); const worker = new Worker(`(()=>{ const { parentPort } = require('worker_threads'); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); // 先接收到管道 parentPort.once('message', (value) => { // 执行子线程的方法 let res = (${funcstr}).apply(this,value.params); res.then((result)=>{ value.threadPort.postMessage(result); value.threadPort.close(); }).catch(err=>{ throw err }) }); console.log('子线程运行成功....') })()`, { eval: true }); let arr = []; for (let i in arguments) { arr[i] = arguments[i] } worker.postMessage({ threadPort: subChannel.port1, params: arr }, [subChannel.port1]); worker.on("exit", () => { //console.log('子线程退出') if (threadConfig && threadConfig.logging) { console.log(`方法${key}在的子线程退出`.cyan) } }) worker.on('error', (err) => { console.log("线程运行报错...", err); reject(err); }) } catch (err) { reject(err) } }) } else { if (isMainThread) { return new Promise((resolve, reject) => { try { const subChannel = new MessageChannel(); const logChannel = new MessageChannel(); // 日志管道 subChannel.port2.on('message', (value) => { //console.log('主线程的port2 接收到:', value); checkReturns(key, value) resolve(value,) }); logChannel.port2.on('message', (value) => { if (threadConfig && threadConfig.logger && _this[threadConfig.logger] ) { if(_this[threadConfig.logger].beforelog) { value = _this[threadConfig.logger].beforelog(value); } _this[threadConfig.logger].apply(_this,value) } }); const worker = new Worker(`(()=>{ let logPort = null; // 通信端口 //向主线程发送日志的方法 function logger() { //console.log("logger "); if(logPort) { logPort.postMessage(Object.assign([],arguments)) } else { console.log("无法传输日志"); } } const { parentPort } = require('worker_threads'); // 先接收到管道 parentPort.once('message', (value) => { try { logPort = value.logPort // 执行子线程的方法 let res = (${funcstr}).apply(this,value.params); if(res instanceof Promise) { res.then((re)=>{ value.threadPort.postMessage(re); value.threadPort.close(); value.logPort.close(); }).catch(err=>{ logger({ message:err.message, stack:err.stack }) }) } else { value.threadPort.postMessage(res); value.threadPort.close(); value.logPort.close(); } } catch(err) { logger({ message:err.message, stack:err.stack }) } }); console.log('子线程运行成功aaa....') })()`, { eval: true }); let arr = []; for (let i in arguments) { arr[i] = arguments[i] } worker.postMessage({ threadPort: subChannel.port1,logPort:logChannel.port1, params: arr }, [subChannel.port1,logChannel.port1]); worker.on("exit", () => { if (threadConfig && threadConfig.logging) { console.log(`方法${key}在的子线程退出`.cyan) } }) } catch (err) { reject(err) } }) } } } else { // 检测是否是异步方法 if (o[key].toString().indexOf("_regenerator[\"default\"].async") != -1) { return o[key].apply(o, arguments).then((result) => { // return o[key].call(o, params).then((result) => { //console.log("异步函数调用结果 是 ", result); // 检测调用的结果 if (result === null || result === false) { return result } checkReturns(key, result) return result; }) } else { //console.log("同步函数调用"); let result = o[key].apply(o, arguments) //let result = o[key].call(o, params) if (result === null || result === false) { return result } if (result instanceof Promise) // 说明返回的结果是一个Promise 对象 { return result.then(res => { if (res === null || res === false) { return res } checkReturns(key, res) return res; }) } else { checkReturns(key, result) return result; } } } }; } else { if (target.$inner.PrivateAttr) { if (target.$inner.PrivateAttr.has(key)) { errorMsg = `Factory getter 异常:类${className}的${key}为私有属性,不可外部访问` throw new Error(errorMsg); } } if (target.$inner.ProtectedAttr) { if (target.$inner.ProtectedAttr.has(key)) { errorMsg = `Factory getter 异常:类${className}的${key}为保护属性,不可外部访问` throw new Error(errorMsg); } } return o[key] } } // 内部控制代理 function _inner_proxy(o, className) { var errorMsg = ""; return new Proxy(o, { get: function (target, key, receiver) { return _getter(o, className, target, key, receiver) }, set(target, key, value) { //console.log("哈哈哈",key) _inner_checkinner(target); if (_inner_checkinner_keywords(key)) { errorMsg = `Factory setter 异常:类${className}的${key}属性或者方法 为内部保留方法/属性,不可直接访问` throw new Error(errorMsg); } if (isFunction(value)) { errorMsg = `Factory setter 异常:无法在外部为类${className}的对象新增${key}方法,方法只能类中定义` throw new Error(errorMsg); } if (!isFunction(value) && isFunction(o[key])) { errorMsg = `Factory setter 异常:类${className}的 ${key} 为方法,无法赋值为一个非函数/方法的值` throw new Error(errorMsg); } if (isFunction(o[key])) { // 检测是否是readonly errorMsg = `Factory setter 异常:类${className}的${key}方法保护,不可随意改动对象的方法` throw new Error(errorMsg); // o[key] = value; // return true; } else //如何是数值的情况 { if ((target.$inner.PrivateAttr && target.$inner.PrivateAttr.has(key)) || (target.$inner.ReadonlyAttr && target.$inner.ReadonlyAttr.has(key)) || (target.$parentInner && target.$parentInner && target.$parentInner.$inner && target.$parentInner.$inner.ReadonlyAttr && target.$parentInner.$inner.ReadonlyAttr.has(key))) { errorMsg = `Factory setter 异常:类${className}的${key}属性为只读或者私有属性,无法赋值` throw new Error(errorMsg); } //console.log("检测schama",target.$parentInner.$inner,key); //检测数据类型是和定义的数据类型一致 //let schame = target.$inner.AttrLimit.get(key); if ((target.$inner.AttrLimit && target.$inner.AttrLimit.get(key)) || (target.$parentInner && target.$parentInner.$inner && target.$parentInner.$inner.AttrLimit && target.$parentInner.$inner.AttrLimit.get(key))) { let schemaRule = null; if (target.$inner.AttrLimit.get(key)) { schemaRule = target.$inner.AttrLimit.get(key); // console.log("@@@",schemaRule); } else if (target.$parentInner.$inner.AttrLimit.get(key)) { schemaRule = target.$parentInner.$inner.AttrLimit.get(key); } else { return; } let schema = _inner_get_schame(schemaRule); if (!schema) { //console.log(key,target.$parentInner.$inner.AttrLimit.get(key),"rule"); errorMsg = `Factory setter 异常:类${className}的 ${key} 属性赋值时,schame校验对象读取失败` throw new Error(errorMsg); } let { error } = schema.validate(value); if (error) { let err = ""; if (error.details && error.details.length >= 0) { for (let e of error.details) { if (!e) { continue; } err += e.message + "、" } } //let err = validateResult && validateResult.error && validateResult.error.ValidationError?validateResult.error.ValidationError:"" errorMsg = `Factory setter 异常:类${className}的 ${key} 属性无法赋值,因为数据类型不匹配,异常信息:${err}` throw new Error(errorMsg); } } o[key] = value; return true; } } }); } // 内部设置属性控制代理 function _setter(target, key, value, className, o) { _inner_checkinner(target); if (_inner_checkinner_keywords(key)) { errorMsg = `Factory setter 异常:类${className}的${key}属性或者方法 为内部保留方法/属性,不可直接访问` throw new Error(errorMsg); } // if (isFunction(value) && !isFunction(o[key])) { // errorMsg = `Factory setter 异常:类${className}的 ${key} 为属性,无法赋值为一个函数/方法` // throw new Error(errorMsg); // } if (isFunction(value)) { errorMsg = `Factory setter 异常:无法在外部为类${className}的对象新增${key}方法,方法只能类中定义` throw new Error(errorMsg); } if (!isFunction(value) && isFunction(o[key])) { errorMsg = `Factory setter 异常:类${className}的 ${key} 为方法,无法赋值为一个非函数/方法的值` throw new Error(errorMsg); } if (isFunction(o[key])) { // 检测是否是readonly // if (target.$inner.ReadonlyMethods && target.$inner.ReadonlyMethods.has(key)) { // errorMsg = `Factory setter 异常:类${className}的${key}方法为只读方法,无法赋值` // throw new Error(errorMsg); // } errorMsg = `Factory setter 异常:类${className}的${key}方法保护,不可随意改动对象的方法` throw new Error(errorMsg); // o[key] = value; // return true; } else //改属性值 { //console.log(target.$parentInner) if ((target.$inner.ReadonlyAttr && target.$inner.ReadonlyAttr.has(key)) || (target.$parentInner && target.$parentInner && target.$parentInner.$inner && target.$parentInner.$inner.ReadonlyAttr && target.$parentInner.$inner.ReadonlyAttr.has(key))) { errorMsg = `Factory setter 异常:类${className}的${key}属性为只读属性,无法赋值` throw new Error(errorMsg); } //console.log("检测schama",target.$parentInner.$inner,key); //检测数据类型是和定义的数据类型一致 //let schame = target.$inner.AttrLimit.get(key); if ((target.$inner.AttrLimit && target.$inner.AttrLimit.get(key)) || (target.$parentInner && target.$parentInner.$inner && target.$parentInner.$inner.AttrLimit && target.$parentInner.$inner.AttrLimit.get(key))) { let schemaRule = null; if (target.$inner.AttrLimit.get(key)) { schemaRule = target.$inner.AttrLimit.get(key); } else if (target.$parentInner.$inner.AttrLimit.get(key)) { schemaRule = target.$parentInner.$inner.AttrLimit.get(key); } else { return; } let schema = _inner_get_schame(schemaRule); if (!schema) { errorMsg = `Factory setter 异常:类${className}的 ${key} 属性赋值时,构造校验schame失败` throw new Error(errorMsg); } let { error } = schema.validate(value); if (error) { let err = ""; if (error.details && error.details.length >= 0) { for (let e of error.details) { if (!e) { continue; } err += e.message + "、" } } //let err = validateResult && validateResult.error && validateResult.error.ValidationError?validateResult.error.ValidationError:"" errorMsg = `Factory setter 异常:类${className}的 ${key} 属性无法赋值,因为数据类型不匹配,异常信息:${err}` throw new Error(errorMsg); } } o[key] = value; return true; } } function _outer_proxy(o, className) { var errorMsg = ""; return new Proxy(o, { get(target, key, receiver) { _inner_checkinner(target); if (_inner_checkinner_keywords(key)) { errorMsg = `Factory getter 异常:类${className}的${key}属性或者方法 为内部保留方法/属性,不可直接访问` throw new Error(errorMsg); } if ((o[key] === undefined) || (o[key] === "undefined")) { console.log(o[key]) errorMsg = `Factory getter 异常:类${className}的${key}属性或者方法 可能不存在` throw new Error(errorMsg); } // 访问权限控制 if (isFunction(o[key])) { if (target.$inner.PrivateMethods) { if (target.$inner.PrivateMethods.has(key)) { errorMsg = `Factory getter 异常:类${className}的${key}为私有方法,不可外部访问` throw new Error(errorMsg); } } if (target.$inner.ProtectedMethods) { if (target.$inner.ProtectedMethods.has(key)) { errorMsg = `Factory getter 异常:类${className}的${key}为保护方法,不可外部访问` throw new Error(errorMsg); } } //判断是异步函数还是同步 // let isAsync = isAsyncFunction(async ()=>{}) // console.log("检测",isAsync); return (params) => { if (o['__call_before']) { if (!o['__call_before'](key, params)) { if (o["__call_stop"]) { o["__call_stop"](key, params) } return; } } //检测传入的parmas是否是正确的 if (target.$inner.$methodsValidate.$params.has(key)) { let schema = Joi.object(target.$inner.$methodsValidate.$params.get(key)); let { error } = schema.validate(params); if (error) { //console.log(error.details) let err = ""; if (error.details && error.details.length >= 0) { for (let e of error.details) { if (!e) { continue; } err += e.message + "、" } } //let err = validateResult && validateResult.error && validateResult.error.ValidationError?validateResult.error.ValidationError:"" errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,Params 参数校验异常,异常信息:${err}` throw new Error(errorMsg); } } // 检测方法返回的结果 function checkReturns(key, value) { if (target.$inner.$methodsValidate.$returns.has(key)) { let schema = Joi.object(target.$inner.$methodsValidate.$returns.get(key)); let { error } = schema.validate(value); if (error) { let err = ""; if (error.details && error.details.length >= 0) { for (let e of error.details) { if (!e) { continue; } err += e.message + "、" } } //let err = validateResult && validateResult.error && validateResult.error.ValidationError?validateResult.error.ValidationError:"" errorMsg = `Factory getter 异常:类${className}的${key}方法调用时,Returns 参数校验异常,异常信息:${err}` throw new Error(errorMsg); } } } if (o[key].toString().indexOf("_regenerator[\"default\"].async") != -1) { return o[key].call(o, params).then((result) => { //console.log("异步函数调用结果 是 ", result); // 检测调用的结果 if (result === null || result === false) { return result } checkReturns(key, result) return result; }) } else { //console.log("同步函数调用"); let result = o[key].call(o, params) if (result === null || result === false) { return result } checkReturns(key, result) return result; } }; } else { if (target.$inner.PrivateAttr) { if (target.$inner.PrivateAttr.has(key)) { errorMsg = `Factory getter 异常:类${className}的${key}为私有属性,不可外部访问` throw new Error(errorMsg); } } if (target.$inner.ProtectedAttr) { if (target.$inner.ProtectedAttr.has(key)) { errorMsg = `Factory getter 异常:类${className}的${key}为保护属性,不可外部访问` throw new Error(errorMsg); } } return o[key] } }, set(target, key, value) { return _setter(target, key, value, className, o) } }); } // 主工厂方法,用于创建对象 function Factory(clas, constructorParams) { //console.log(clas.prototype.geto,"hahah111"); let className = ""; var errorMsg = ""; if (!clas || !clas.prototype || !clas.prototype.constructor || !clas.prototype.constructor.name) { errorMsg = `Factory异常:构造对象失败,因为传入了一个不合法的类` throw new Error(errorMsg); } className = clas.prototype.constructor.name; let o = new clas(); let innerAttr = {}; for (let i in o) { if (!i) { continue } innerAttr[i] = o[i]; } o.setter = new Proxy(o, { set(target, key, value) { //console.log("内部setter", target.$inner); return _setter(target, key, value, className, o); } }); o.getter = new Proxy(o, { get: function (target, key, receiver) { return _getter(o, className, target, key, receiver, 'inner') } }); // o.getter = new Proxy(o, { // set(target, key, value) { // //console.log("内部setter", target.$inner); // return _setter(target, key, value, className, o); // } // }); // 这里用于控制类的外部调用 let descObj = _inner_proxy(o, className) let $inner = descObj.$getInner(); if ($inner.$constructor) { //console.log("实例化对象", o[$inner.$className]); // 构造方法不能是异步方法 if (o[$inner.$className].toString().indexOf("_regenerator[\"default\"].async") != -1) { errorMsg = `Factory异常:构造对象失败,构造方法不能是异步方法` throw new Error(errorMsg); } let $parentInner = descObj.$getParentInner(); // 设置父类的构造方法到super对象 if ($parentInner && $parentInner.$inner.$constructor) { let paramsSchema = $parentInner.$inner.$methodsValidate.$params.get($parentInner.$inner.$className); descObj.$setParentsConstuctor((parentsConstuctorParams) => { _inner_check_params(paramsSchema, parentsConstuctorParams, $parentInner.$inner.$className, "构造方法"); $parentInner.$inner.$constructor(parentsConstuctorParams); let parentsobj = descObj.$getParentObj(); parentsobj.$setHandleConstructor(); }) } // 执行构造方法 let paramsSchema = $inner.$methodsValidate.$params.get($inner.$className); _inner_check_params(paramsSchema, constructorParams, $inner.$className, "构造方法"); $inner.$constructor.call(o, constructorParams); descObj.$setHandleConstructor();// 表示实例化成功 // 检测父类的构造方法 if ($parentInner && $parentInner.$inner.$constructor && !$parentInner.$inner.$isHandleConstructor) { errorMsg = `Factory异常:构造对象失败,父类${$parentInner.$inner.$className}中自定义了构造方法,必须在子类的构造方法中执行` throw new Error(errorMsg); } //console.log("父类的", $parentInner); } return descObj; } //访问控制符 function Private(target, name) { _inner_checkinner(target); var errorMsg = ""; if (isFunction(target[name])) { // 检测是否已经被其他的访问修饰符修饰了 if (target.$inner.PublicMethods && target.$inner.PublicMethods.has(name)) { errorMsg = `@Private修饰报错:${name}方法已经被@Public 修饰过,无法重复修饰` throw new Error(errorMsg); } if (target.$inner.ProtectedMethods && target.$inner.ProtectedMethods.has(name)) { errorMsg = `@Private修饰报错:${name}方法已经被@Protected 修饰过,无法重复修饰` throw new Error(errorMsg); } if (!target.$inner.PrivateMethods || target.$inner.PrivateMethods.size == 0) { target.$inner.PrivateMethods = new Set(); } target.$inner.PrivateMethods.add(name, target.$inner.PublicMethods); //console.log("设置方法的私有访问权限", name,target.$inner.PublicMethods) } else { if (target.$inner.PublicAttr && target.$inner.PublicAttr.has(name)) { errorMsg = `@Private修饰报错:${name}属性已经被@Public 修饰过,无法重复修饰` throw new Error(errorMsg); } if (target.$inner.ProtectedAttr && target.$inner.ProtectedAttr.has(name)) { errorMsg = `@Private修饰报错:${name}属性已经被@Protected 修饰过,无法重复修饰` throw new Error(errorMsg); } if (!target.$inner.PrivateAttr || target.$inner.PrivateAttr.size == 0) { target.$inner.PrivateAttr = new Set(); } target.$inner.PrivateAttr.add(name); //console.log("设置属性的私有访问权限", name) } } // //访问控制符 function Public(target, name, descriptor) { _inner_checkinner(target); if (_inner_checkinner_keywords(name)) { errorMsg = `定义方法或者属性异常:${name}属性或者方法 为内部保留方法/属性,不可重新定义` throw new Error(errorMsg); } if (isFunction(target[name])) { // 检测是否已经被其他的访问修饰符修饰了 if (target.$inner.PrivateMethods && target.$inner.PrivateMethods.has(name)) { errorMsg = `@Public修饰报错:${name}方法已经被@Private 修饰过,无法重复修饰` throw new Error(errorMsg); } if (target.$inner.ProtectedMethods && target.$inner.ProtectedMethods.has(name)) { errorMsg = `@Public修饰报错:${name}方法已经被@Protected 修饰过,无法重复修饰` throw new Error(errorMsg); } if (!target.$inner.PublicMethods || target.$inner.PublicMethods.size == 0) { target.$inner.PublicMethods = new Set(); } target.$inner.PublicMethods.add(name); //console.log("设置方法的公有访问权限", name,target.$inner.PublicMethods) } else { if (target.$inner.PrivateAttr && target.$inner.PrivateAttr.has(name)) { errorMsg = `@Public修饰报错:${name}属性已经被@Private 修饰过,无法重复修饰` throw new Error(errorMsg); } if (target.$inner.ProtectedAttr && target.$inner.ProtectedAttr.has(name)) { errorMsg = `@Public修饰报错:${name}属性已经被@Protected 修饰过,无法重复修饰` throw new Error(errorMsg); } if (!target.$inner.PublicAttr || target.$inner.PublicAttr.size == 0) { target.$inner.PublicAttr = new Set(); } target.$inner.PublicAttr.add(name); } } // //访问控制符 function Protected(target, name, descriptor) { _inner_checkinner(target); if (isFunction(target[name])) { if (target.$inner.PrivateMethods && target.$inner.PrivateMethods.has(name)) { errorMsg = `@Protected修饰报错:${name}方法已经被@Private 修饰过,无法重复修饰` throw new Error(errorMsg); } if (target.$inner.PublicMethods && target.$inner.PublicMethods.has(name)) { errorMsg = `@Protected修饰报错:${name}方法已经被@Public 修饰过,无法重复修饰` throw new Error(errorMsg); } if (!target.$inner.ProtectedMethods || target.$inner.ProtectedMethods.size == 0) { target.$inner.ProtectedMethods = new Set(); } target.$inner.ProtectedMethods.add(name); } else { if (target.$inner.PrivateAttr && target.$inner.PrivateAttr.has(name)) { errorMsg = `@Protected修饰报错:${name}属性已经被@Private 修饰过,无法重复修饰` throw new Error(errorMsg); } if (target.$inner.PublicAttr && target.$inner.PublicAttr.has(name)) { errorMsg = `@Protected修饰报错:${name}属性已经被@Public 修饰过,无法重复修饰` throw new Error(errorMsg); } if (!target.$inner.ProtectedAttr || target.$inner.ProtectedAttr.size == 0) { target.$inner.ProtectedAttr = new Set(); } target.$inner.ProtectedAttr.add(name);