Почему func() не выполняется полностью, когда я прерываю работу вложенного sleep() удалением таймера?

Пытаюсь разобраться с асинхронностью (promise,async,await). Не понимаю, почему после нажатия на блок, func() не продолжает выполняться, сообщение "после sleep" не выводится в консоль. И как сделать, чтобы это сообщение все-таки выводилось.

let timerId;

function deleteTimer(){
console.log("таймер остановлен");
clearTimeout(timerId);
}


function sleep(ms) {
  return new Promise(resolve => timerId=setTimeout(resolve, ms));
}
 
async function func() {
  console.log("до sleep");
  await sleep(10000);
  console.log("после sleep");
}
 
func();
<!doctype html>

<html lang="en">
<head>
  <meta charset="utf-8">
  <title>test</title>
</head>

<body>
  <style>
    div {
      height:100px;
      width:100px;
      background-color:aquamarine;
      text-align: center;
    }
  </style>
  <div onclick="deleteTimer()">Нажми на меня</div>
  <script src="js.js"></script>
</body>
</html>


Ответы (1 шт):

Автор решения: vsemozhebuty

Если действительно нужно сделать что-то близкое к вашему коду, можно попробовать так:

let timerId;
let outerResolve;

function deleteTimer() {
  console.log("таймер остановлен");
  clearTimeout(timerId);
  outerResolve();
}

function sleep(ms) {
  return new Promise((resolve) => {
    outerResolve = resolve;
    timerId = setTimeout(resolve, ms);
  });
}
 
async function func() {
  console.log("до sleep");
  await sleep(10000);
  console.log("после sleep");
}
 
func();
<body>
  <style>
    div#stop {
      height:100px;
      width:100px;
      background-color:aquamarine;
      text-align: center;
    }
  </style>
  <div id="stop" onclick="deleteTimer()">Нажми на меня</div>
  <script src="js.js"></script>
</body>

Можно ещё попробовать Promise.race():

function processClick() {
  return new Promise((resolve) => {
    document.querySelector('div#stop').addEventListener(
      'click',
      () => {
        console.log("таймер остановлен");
        resolve();
      },
      { once : true });
  });
}

function sleep(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}
 
async function func() {
  console.log("до sleep");
  await Promise.race([
    sleep(10000),
    processClick(),
  ]);
  console.log("после sleep");
}
 
func();
<body>
  <style>
    div#stop {
      height:100px;
      width:100px;
      background-color:aquamarine;
      text-align: center;
    }
  </style>
  <div id="stop">Нажми на меня</div>
  <script src="js.js"></script>
</body>

→ Ссылка