You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:43:35