class FrameNotice extends Component {
private _onNextUpdate!: () => void;
static inst?: FrameNotice;
protected start() {
if (!this._onNextUpdate) {
this.setNextUpdate();
}
}
setNextUpdate() {
const next = new Promise<void>(resolve => this._onNextUpdate = resolve);
FrameNotice._nextUpdate = next;
}
protected update() {
this._onNextUpdate();
this.setNextUpdate();
}
static _nextUpdate = Promise.resolve();
protected onDestroy(): void {
delete FrameNotice.inst;
this._onNextUpdate();
}
}
export function nextFrame() {
const scene = director.getScene();
if (!scene) {
return new Promise(r => requestAnimationFrame(r));
}
if (!FrameNotice.inst) {
const node = new Node('FrameNotice');
node.parent = scene;
FrameNotice.inst = node.addComponent(FrameNotice);
director.addPersistRootNode(node);
FrameNotice.inst.setNextUpdate();
}
return FrameNotice._nextUpdate;
}
1赞
好像像下面这样也行
this.scheduleOnce(()=>{
// next frame cb
cb();
})
1赞
你这个实现看过去有问题啊。你当前帧如果还没有 update 的话。(比如别的组件先 update,里面触发了等待下一帧的逻辑)然后,你这 update 导致当前帧就 resolve 了
1赞
如果在component内部,还是使用scheduleOnce比较好,省去了await之后判断Node.isValid的麻烦
2赞
你说得对,确实不适合在update回调中使用我这个
是的,我这个主要就是想设计一个在组件外可以调用的工具方法。
可以简单封装一下 setTimeout 或者 requestAnimationFrame:
function wait(timeout = 0) {
return new Promise(resolve => setTimeout(resolve, timeout));
}
function nextFrame() {
return new Promise(resolve => requestAnimationFrame(resolve));
}
// test
(async function () {
console.log(1, performance.now());
await wait(1000);
console.log(2, performance.now());
await nextFrame();
console.log(3, performance.now());
})();

我自己单独写了个计时器的工具