You need to enable JavaScript to run this app. 如何不使用async/await,在Promise完成后用Immer.js修改draft对象
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用async/await,在Promise完成后用Immer.js修改draft对象

问题原因

报错本质是Immer的draft代理生命周期规则导致的:

  • 当你给produce传入同步函数时,Immer会在函数同步执行结束后立刻销毁(revoke)draft代理对象,后续任何对该draft的操作都会触发illegal operation attempted on a revoked proxy错误。
  • async/await写法能正常运行,是因为async函数默认返回Promise,Immer内置支持异步producer:如果produce检测到回调返回Promise,会等该Promise决议完成后再销毁draft代理。
  • 第二个写法的问题在于:produce的回调里只是启动了异步Promise链,但没有把这个Promise返回给produce,produce认为回调同步执行完毕就直接销毁了draft,等Promise.resolve(5).then触发修改draft的时候,代理已经失效了。
修改方案

只要在produce的回调里把你构造的Promise链返回即可,让Immer感知到有异步逻辑需要等待:

import produce from 'immer';

Promise.resolve({ eggs: 0 }).then(
  produce((eggCounter) => { 
    // 返回Promise,让Immer等待异步逻辑完成后再销毁draft
    return Promise.resolve(5).then((n) => eggCounter.eggs += n) 
  })
).then(console.log)
效果验证

修改后代码运行逻辑和async/await版本完全等价,最终会输出{ eggs: 5 },不会再触发代理撤销错误。

内容的提问来源于stack exchange,提问作者pixatlazaki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 01:27:05