我正在用Node JS构建一个猜谜游戏。在后端收集了一些数据后,我将其发送到前端,游戏就开始了。数据包含所有10个级别,因此游戏可以在一个页面上运行。每级运行10秒。时间到后,将用户选择发送到服务器,并返回结果。显示答案,然后将内容更改为“下一级”(使用大数据对象中的内容,因此不需要刷新)。
我遇到了一些问题,让10个级别每个级别运行10秒(或者大约12秒,延迟显示结果)。
这不能在某种类型的循环中完成,因为每个级别的所有awaits都将同时运行。例如:
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
for (let i = 0; i < 10; i++) {
displayPage(i);
await timeout(10000);
const result = await $.post(...) // gets results
displayResults(result);
await timeout(2000);
}所有的timeout都会一次运行,但它不会工作。
我想过使用setInterval,但我不确定如何..因为我想等待10秒,直到检查输入,然后显示结果2秒,然后继续。
目前,我得出的结果是:
displayPage(level1);
await timeout(10000);
const result = await $.post(...)
displayResults(result);
await timeout(2000);
displayPage(level2);
await timeout(10000);
const result = await $.post(...)
displayResults(result);
await timeout(2000);
displayPage(level3);
await timeout(10000);
const result = await $.post(...)
displayResults(result);
await timeout(2000);
displayPage(level4);
await timeout(10000);
const result = await $.post(...)
displayResults(result);
await timeout(2000);
...这似乎不是很有效,我认为有更好的方法来做到这一点,但我不确定如何做。如有任何建议,我们将不胜感激。谢谢!
发布于 2019-10-28 05:47:56
我想这就是你要找的:
const pages = [1, 2, 3, 4, 5];
run();
async function run() {
for (let i = 0; i < pages.length; i++) {
await displayPage(i);
const result = 'Some result';
await displayResult(result);
}
}
function displayPage(number) {
text.innerText = 'Page ' + number;
return new Promise(res => {
setTimeout(res, 10000);
});
}
function displayResult(result) {
text.innerText = 'Result: ' + result;
return new Promise(res => {
setTimeout(res, 2000);
});
}<div id="text"><div>
另一种解决方案,没有承诺和循环:
const pages = [1, 2, 3, 4, 5];
let currentPageIndex = 0;
displayPage();
function displayPage() {
const index = currentPageIndex++;
if (pages[index] === undefined) return;
const pageNumber = pages[index];
text.innerText = 'Page ' + pageNumber;
const result = 'Some result';
setTimeout(() => {
displayResult(result);
}, 10000);
}
function displayResult(result) {
text.innerText = 'Result: ' + result;
setTimeout(() => {
displayPage();
}, 2000);
}<div id="text"></div>
发布于 2019-10-28 05:28:00
你的第一个选择似乎是有效的,假设它被包装在一个异步函数中:
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
const testFunc = async () =>{
for (let i = 0; i < 10; i++) {
console.log('page' , i+1 , '- question')
await timeout(3000);
console.log('page' , i+1 , '- answer')
await timeout(1000);
}
}
testFunc()
发布于 2019-10-28 05:45:24
在大约1000ms上使用setInterval创建worker,并添加一个切换播放(10s)和等待(2s)的状态机。您需要一个对服务器执行post调用的过程和一个对象来保存数据(级别和内容)。
例如:
setInterval(funcWorker,1000,s_gameObj);
function funcWorker(f_context){
var l_dateNow = new Date();
if(f_context.is_playing){
var l_elapsed = l_dateNow.getTime() - f_context.dateLevelStart.getTime();
if(l_elapsed.totalSeconds() >= f_context.LEVEL_TIME){
f_context.end_level();
}
}else if(f_context.is_waiting_user){
//same check as above but on the waiting start
....
f_context.next_level();
}else if(f_context.is_waiting_server){
//do whatever
}
}end_level()应该在上下文(游戏)对象中设置状态标志,以发送和发送到服务器。当服务器返回响应函数时,将状态设置为waiting user,并将相应的时间变量初始化为now()。next_level()应将状态设置为播放,并将相应的时间变量初始化为now(),以便计时器可以计数。将上面的代码视为参考,而不是复制-粘贴资源。
https://stackoverflow.com/questions/58583385
复制相似问题