Saya sedang membangun game menebak dengan Node JS. Setelah mengumpulkan beberapa data di back-end, saya mengirimkannya ke front-end dan permainan dimulai. Data berisi semua 10 level, sehingga game dapat berjalan di satu halaman. Setiap level berjalan selama 10 detik. Setelah waktu habis, pilihan pengguna dikirim ke server, dan hasilnya kembali. Jawabannya ditampilkan, dan kemudian konten diubah ke "tingkat berikutnya" (menggunakan konten di objek data besar, oleh karena itu tidak diperlukan penyegaran).

Saya mengalami beberapa masalah dengan menjalankan 10 level masing-masing selama 10 detik (atau ~ 12 detik dengan penundaan untuk menampilkan hasilnya).

Ini tidak dapat dilakukan dalam beberapa jenis loop, karena semua awaits untuk setiap level akan berjalan sekaligus. Contohnya:

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);
}

Semua timeout akan berjalan sekaligus, dan itu tidak akan berhasil.

Saya berpikir untuk menggunakan setInterval, tetapi saya tidak yakin bagaimana caranya.. karena saya ingin menunggu 10 detik hingga memeriksa input, dan kemudian menampilkan hasilnya selama 2 detik, lalu melanjutkan.

Untuk saat ini hasil yang saya dapatkan adalah:

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);

...

Ini sepertinya tidak efisien dan saya pikir ada cara yang lebih baik untuk melakukan ini, tetapi saya tidak yakin bagaimana caranya. Setiap saran akan dihargai. Terima kasih!

0
ethanpasta 28 Oktober 2019, 00:08

3 jawaban

Jawaban Terbaik

Saya pikir ini yang Anda cari:

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>

Solusi lain, tanpa janji dan loop:

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>
0
Andrew Dashkov 27 Oktober 2019, 22:38

Gunakan setInterval pada sekitar 1000 md untuk membuat pekerja dan menambahkan mesin status yang mengaktifkan pemutaran (10 detik) dan menunggu (2 detik). Anda memerlukan prosedur yang melakukan panggilan pos ke server dan objek untuk menyimpan data (level dan lainnya).

Sebagai contoh:

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() harus mengatur bendera negara dalam objek context(game), untuk mengirim dan mengirim ke server. Saat server kembali dalam fungsi respons, atur status ke pengguna yang menunggu dan initkan variabel waktu yang sesuai ke now(). next_level() harus mengatur status untuk diputar dan init variabel waktu yang sesuai ke now() sehingga pengatur waktu dapat menghitung. Pertimbangkan kode di atas sebagai referensi dan bukan sebagai sumber copy-paste.

0
tstoev 27 Oktober 2019, 21:45

Opsi pertama Anda tampaknya berfungsi dengan asumsi itu dibungkus dalam fungsi async:

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()
0
Willman.Codes 27 Oktober 2019, 21:27