Javascript диалоговое окно с приостановкой / возобновлением потока - PullRequest
0 голосов
/ 13 апреля 2020

Я создаю диалоговое окно в слое HTML в Javascript. Когда я звоню, я хочу, чтобы он вел себя так же, как при вызове встроенного окна оповещения. Он должен выдавать поток GUI при вызове, а затем возобновлять выполнение со следующей строки кода, когда он закрыт. С точки зрения вызывающего, он действует так, как будто он блокирует поток GUI. Это возможно в Javascript?

В основной функции, приведенной ниже, я хочу, чтобы состояние выполнения функции сохранялось прямо при вызове showDialog. Затем отображается диалоговое окно, которое получает события щелчка и т. Д. c, и когда оно, наконец, закрывается, я хочу, чтобы возвращаемое значение было возвращено в переменную результата, и выполнение возобновляется в основной функции. Возможно ли это как-то? Я не собираюсь фактически блокировать поток GUI, потому что тогда диалог не будет работать.

function main()
{
  // Show the dialog to warn
  let result = showDialog("Warning", "Do you want to continue?", ["OK", "Cancel"]);

  // Do some stuff.
  if (result === "OK") performAction(); 
}

// This function shows a custom modal dialog (HTML layer), and should only return the GUI 
// thread when the user has clicked one of the buttons.
function showDialog(title, text, buttons)
{
  // Code here to draw the dialog and catch button events.
}

Ответы [ 2 ]

1 голос
/ 13 апреля 2020

Из-за природы Javascript вы не можете заблокировать код. Единственный способ - использовать таймер для проверки возвращаемого значения, обещаний или, что лучше, обратного вызова:

function main()
{
  showDialog({
    title: "Warning", 
    text: "Do you want to continue?", 
    buttons: ["OK", "Cancel"],
    onClose: function(result) {
      if (result == "OK") {
        performAction1();
      } else {
        console.log("Cancelled");
      }
    }
  });
}

function showDialog(options)
{
   $("#dialog .title").innerText = options.title;
   $("#dialog .text").innerText = options.text;
   $(".button").hide();
   for (var i = 0; i < options.buttons.length; i++) {
     $(".button:nth-child(" + i + ")")
       .show()
       .innerText(options.buttons[i])
       .click(() => {
         $("#dialog").hide();
         options.onClose(options.buttons[0]); // Perform the callback
       }
   }
   #("#dialog").show();
}
0 голосов
/ 14 апреля 2020

Оказывается, что async / await может делать только то, что мне нужно. Вызов функции с использованием ключевого слова await будет «блокировать» поток в этой точке, пока не будет выполнено обещание функции. Чтобы использовать ключевое слово await, основная функция должна использовать ключевое слово asyn c.

async function main()
{
  let dialog = new CustomDialog();
  let result = await dialog.show();
  if (result === "OK") performAction();
}

class CustomDialog
{
  constructor()
  {
    this.closeResolve = null;
    this.returnValue = "OK";
  }
  show()
  {
    // Code to show the dialog here

    // At the end return the promise
    return new Promise(function(resolve, reject) 
    { 
      this.closeResolve = resolve; 
    }.bind(this));
  }

  close()
  {
     // Code to close the dialog here

     // Resolve the promise
     this.closeResolve(this.returnValue);
  }
}

...