为什么promise解析后await后面的语句不继续执行?

问题描述 投票:0回答:1

我想实现一个异步任务调度。这是我的代码:

let gameTick = 0;

const tasks: Record<string, Function[]> = {};

function sleep(t: number) {
    const targetTick = gameTick + t;
    if (!tasks[targetTick]) {
        tasks[targetTick] = [];
    }
    return new Promise<void>(resolve => {
        tasks[targetTick].push(resolve);
    });
}

async function task1() {
  print('start task1');
  for (let i = 0; i < 3; i++) {
    print(`execute: ${i}`);
    await sleep(2);
  }
}

// task1();

for (gameTick = 0; gameTick < 10; gameTick++) {
    print(`tick: ${gameTick}`);
    tasks[gameTick]?.forEach(f => f())
    if (gameTick == 2) task1();
}

这段代码在 TypeScriptToLua 环境和 node.js 环境中的行为不同,这让我很困惑。

TypeScriptToLua nodejs
勾选:0 勾选:0
勾选:1 勾选:1
勾选:2 勾选:2
开始任务1 开始任务1
执行:0 执行:0
勾选:3 勾选:3
打勾:4 打勾:4
执行:1 打勾:5
打勾:5 打勾:6
打勾:6 打勾:7
执行:2 打勾:8
打勾:7 打勾:9
打勾:8 执行:1
打勾:9

我能理解TypeScriptToLua的流程,相当于resolve后恢复协程,await后立即执行代码。但我不懂 NodeJ。为什么循环结束后还继续执行,而且只执行一次?

node.js lua
1个回答
0
投票

问题在于 Promise 是异步的,但你的游戏循环是同步的。当您调用

resolve()
时,不会直接继续执行协程。它仅解析 Promise,从而安排任何已注册的 Promise 反应(例如,
await
该 Promise 的异步代码的延续,或通过
.then()
添加的回调函数)在下一个微任务中尽快运行。因此,在运行下一个游戏之前,您需要给它一些时间来完成此操作:

(tasks[2] ??= []).push(task1);

for (gameTick = 0; gameTick < 10; gameTick++) {
    print(`tick: ${gameTick}`);
    tasks[gameTick]?.forEach(f => f())
    await Promise.resolve(); // if not even setTimeout()
}
© www.soinside.com 2019 - 2024. All rights reserved.