【问题标题】:Javascript dialog box with thread pause/resume带有线程暂停/恢复的 Javascript 对话框
【发布时间】:2020-04-13 09:26:34
【问题描述】:

我正在用 Javascript 在 HTML 层中制作一个对话框。当我调用它时,我希望它的行为就像我调用内置警报框时一样。它应该在调用时产生 GUI 线程,然后在它关闭时在下一个代码行上恢复执行。从调用者的角度来看,它的行为就好像它阻塞了 GUI 线程。这在 Javascript 中可行吗?

在下面的主函数中,我希望在调用 showDialog 时保留函数的执行状态。然后显示对话框,并接收点击事件等,当它最终关闭时,我希望将返回值传递回结果变量并在主函数中恢复执行。这有可能吗?我并没有考虑实际阻塞 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.
}

【问题讨论】:

  • 这能解决您的问题吗? stackoverflow.com/questions/6807799/…
  • 谢谢@Shubham。确实如此。我知道承诺和回调方法。这就是我目前用来解决问题的方法。但我认为它使代码丑陋且难以阅读。所以我希望我可以巧妙地使用 yield 关键字,但我还没有弄明白。

标签: javascript modal-dialog closures ui-thread


【解决方案1】:

事实证明,async/await 可以满足我的需要。使用 await 关键字调用函数将在该点“阻塞”线程,直到函数的承诺得到解决。为了能够使用 await 关键字,main 函数必须使用 async 关键字。

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

【讨论】:

  • 我喜欢这种模式 - 让事物更接近参照透明和可读性。
【解决方案2】:

由于 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();
}

【讨论】:

  • 谢谢爱丽儿。我希望避免回调或承诺,因为它们使代码难以阅读,尤其是当您有一系列多个对话框时,但我想我现在被它们困住了。
猜你喜欢
  • 1970-01-01
  • 2015-02-21
  • 2012-07-13
  • 1970-01-01
  • 1970-01-01
  • 2016-03-24
  • 1970-01-01
  • 2010-12-28
  • 2011-01-07
相关资源
最近更新 更多