对啊,你说的传入 cancel,就是框架层提供了断开机制
这个有很多种解决方案啊
我可以理解为“底层人”不作为么?有可能“设计者”本身不需要编程,就为难普通人,程序员发明语言为难程序员。
我是不太喜欢过度封装, 老老实实isValid很丢人吗
人和代码有一个能跑就行了 
难道你用回调就不需要判断isValid了吗?
自己封装下promise呗,然后建个基类管理下
难道你用回调就不需要判断isValid了吗?
你都异步了为啥不加个事件通知处理呢,只要销毁的时候移除事件监听不就好了
但是调试比较蛋疼
const perfab=await load(…)//等待加载资源完成
const node=cc.clone(prefab)
node.runAction(xxxx)
node…
this.xxxxx
…
楼主说的类似这种情况吧 await之后的所有执行
哦,那我理解错了,我以为回调的情况呢
习惯加就好了
用装饰器呀,比如你定制一个函数的装饰器,这个装饰器可以看作是对函数功能拓展,比如你说的安全性校验,就可以放到装饰器内
function promise_function(_: any, __: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = async function (...args: any[]) {
// 执行前节点校验
if (!cc.isValid(this.node)) {
cc.warn(`[promise_function] node invalid before executing ${original.name}`);
return;
}
try {
const result = await original.apply(this, args);
// 执行后再校验一次
if (!cc.isValid(this.node)) {
cc.warn(`[promise_function] node invalid after executing ${original.name}`);
return;
}
return result;
} catch (err) {
cc.error(`[promise_function] error in ${original.name}:`, err);
}
};
return descriptor;
}
假设function1 是一个await,
@promise_function
async function1 () {
const res = await this.fakeAsyncLoad();
this.node.setPosition(cc.v3(0, 0, 0)); // 如果 node 已经被销毁,就不会走到这里
} 在项目中,我是这么使用的
以下是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 })
isValid越少,说明封装越深,说明适用范围越少。
所以不要在乎这些,适用自己就行了。
和 界面结合起来就得判断。有时候还得 try catch. 烦
额 fakeAsyncLoad完成后 this没了 不一样吗