使用Proxy模拟异步构建器模式API时数组可迭代性丢失问题
解决Mock Knex时数组失去可迭代性的问题
你的问题根源在于:mock函数将所有数据(包括数组)的原型直接替换为基于空对象的Proxy,切断了数组与Array.prototype的关联,导致数组丢失了迭代器(Symbol.iterator)等核心方法,同时then属性的处理逻辑不符合Promise规范,最终让await返回的对象失去了数组特性。
修改后的Mock函数
const mock = (data) => { const orgData = structuredClone(data); // 根据数据类型选择对应的原生原型作为Proxy目标 const targetProto = Array.isArray(data) ? Array.prototype : Object.prototype; Object.setPrototypeOf( data, new Proxy(targetProto, { get(_, prop) { // 按Promise规范处理then,确保await能正确解析出原始数据 if (prop === 'then') { return (resolve) => resolve(orgData); } // 保留原生原型上的Symbol方法(比如数组的迭代器) if (typeof prop === 'symbol') { return Reflect.get(targetProto, prop); } // 链式调用继续返回mock包装后的对象 return () => mock(orgData); }, }) ); return data; };
关键修改说明
- 区分数据类型设置原型:针对数组使用
Array.prototype作为Proxy的target,确保数组能继承Array.prototype上的所有方法(包括迭代器、map、filter等),普通对象则使用Object.prototype - 规范then方法处理:不再直接返回原始数据,而是返回符合Promise规范的then方法,让
await正确解析出未被篡改原型的原始数组 - 正确处理Symbol属性:从原生原型上获取Symbol对应的方法,而不是返回原始数据,保证数组的迭代、toString等特性正常
测试验证
运行以下代码即可正常解构数组:
const mm = mock([ { name: 'user', }, ]); const run = async () => { const res = await mm.select('*').where('name', 'user'); const [first] = res; console.log(first); // 输出 { name: 'user' } }; run();
内容的提问来源于stack exchange,提问作者srinesha
相关产品推荐
相关产品推荐

