await或者异步回调用多了,得加isValid判断,搞得整个人都提心掉胆的

以下是AI给的建议,未实际验证.

// config flags(按你的项目常量来,用 CC_DEBUG / CC_DEV 也行)
const __DEV__ = typeof CC_DEBUG !== 'undefined' ? CC_DEBUG : true;

type Options = {
  log?: boolean;       // 是否打印 warn/error
  rethrow?: boolean;   // 发生异常后是否继续抛出给上层
  afterCheck?: boolean;// 是否在 await 后再二次校验(默认 true)
};
export function promise_function(options: Options = {}) {
  const { log = __DEV__, rethrow = true, afterCheck = true } = options;

  return function (_: any, __: string, descriptor: PropertyDescriptor) {
    const original = descriptor.value;

    descriptor.value = async function (...args: any[]) {
      // 1) 执行前校验
      const node: cc.Node | undefined = (this as any)?.node;
      if (!node || !cc.isValid(node, true)) { // 第二个参数true: 包括正在销毁的情况
        if (log) cc.warn('[promise_function] node invalid before:', original.name);
        return;
      }

      try {
        const ret = await original.apply(this, args);

        // 2)(可选)执行后再校验一次,防“中途被销毁”
        if (afterCheck) {
          if (!cc.isValid(node, true)) {
            if (log) cc.warn('[promise_function] node invalid after:', original.name);
            return;
          }
        }
        return ret;
      } catch (err) {
        if (log) cc.error('[promise_function] error in', original.name, err);
        if (rethrow) throw err; // 默认:记录后继续抛,让上层能感知
        return;
      }
    };

    return descriptor;
  };
}

使用:

@promise_function({ log: true, rethrow: true }) // 开发期
async function1 () {
  const res = await this.fakeAsyncLoad();
  this.node.setPosition(cc.v3(0, 0, 0));
}

// 需要极致性能的构建(发布态)可以这样统一关闭日志:
@promise_function({ log: false, rethrow: true })

1赞

isValid越少,说明封装越深,说明适用范围越少。
所以不要在乎这些,适用自己就行了。

和 界面结合起来就得判断。有时候还得 try catch. 烦

额 fakeAsyncLoad完成后 this没了 不一样吗

isvaild不丢人,主要是担心项目组又来了应届毕业生,review代码的时候提心吊胆的 :rofl: :rofl: :rofl:

确实,老老实实判断下节点或者资源状态挺好的,方便查看和调试。就怕新人来搞些不一样的花活 :sweat_smile:

对于界面上的虚拟列表上的节点,有时候加了 isVaild 也不行,还得加别的判断 哈哈哈哈

解决方案就是把isValid自己封装在框架里,或者用语法糖编译后生成。。。 你真的需要这样的方案吗

新人一来就给底层封装好的逻辑加几个if判断,看明白代码是很难的,最后觉得,直接来个if搞一下能跑就行 :crazy_face:

可以说说语法糖怎么是西安编译后生成吗

哈哈哈说实话,语法糖用多了也提心吊胆啊,不觉得吗?有次问了ai一个语法糖,在浏览器上运行没问题,结果小游戏上跑出来是另一个结果,查半天才查出来

装饰器也是语法糖啊

可选链( ?. )只能避免 “undefined/null” 报错,但在 Cocos 中 “失效对象(destroyed node/component)” 不是 null,也不是 undefined,所以不能靠可选链防止报错

你这个是可以解决问题,就是要多写很多同类型的代码。而且后期会增加理解成本。
以前我游戏流程组合动画多,我就在Component.prototype.Promise 写了个方法,没出过一次问题