【问题标题】:Resolve promise inside an event handler [duplicate]在事件处理程序中解决承诺 [重复]
【发布时间】:2021-11-28 21:12:53
【问题描述】:

代码也可在fiddle 获得。这是我项目中最小的可重现样本。

<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
  <button class="alert">Do stuff</button>
</body>

<template id="modal_template">
    <div class="modal_background">
        <div class="modal_content">
            <h2 class="modal_header"></h2>
            <p class="modal_message"></p>
            <button class="modal_button modal_accept_button"></button>
        </div>
    </div>
</template>
</html>
async function display_modal(title, message, button_label = "Accept") {
  // resolve promise when accept is clicked
  return new Promise((resolve) => {
    
    // create a modal from template
    const temp = document.querySelector("#modal_template");
    let clone = temp.content.cloneNode(true);
    clone.querySelector(".modal_header").innerText = title;
    clone.querySelector(".modal_message").innerText = message;

    // create an accept button
    const button = clone.querySelector(".modal_accept_button");
    button.innerText = button_label;
    button.addEventListener("click", (e) => {
      // On click, delete modal and resolve the promise
      const modal_background = e.srcElement.parentNode.parentNode;
      modal_background.parentNode.removeChild(modal_background);
      resolve();
    });

    document.body.appendChild(clone);
  });
}

window.onload = () => {
  const alert = document.querySelector(".alert");
  alert.addEventListener("click", () => {
    display_modal("Alert", "Important message", "Accept").then(console.log("Accept button clicked"));
  });
}

预期行为

  1. 用户点击“做事”按钮
  2. Modal 出现并提供一些按钮供用户点击。
  3. 模态框上的按钮被点击。
  4. console.log("Accept button clicked") 正在运行,模式已被删除。

实际行为

  1. 用户点击按钮“做事”。 console.log("Accept button clicked") 已运行。
  2. Modal 出现并提供一些按钮供用户点击。
  3. 模态框上的按钮被点击。
  4. 模态框被删除。

当前代码:

window.onload = () => {
  const alert = document.querySelector(".alert");
  alert.addEventListener("click", () => {
    display_modal("Alert", "Important message", "Accept").then(console.log("Accept button clicked"));
  });
}

当前的行为感觉如下:

window.onload = () => {
  const alert = document.querySelector(".alert");
  alert.addEventListener("click", () => {
    display_modal("Alert", "Important message", "Accept");
    console.log("Accept button clicked");
  });
}

为什么会这样?

【问题讨论】:

标签: javascript promise addeventlistener


【解决方案1】:

您错误地将 console.log 传递给 then。然后期望一个函数,你传递任何 console.log 返回。但是为了获得可能的参数,console.log 会立即执行。

最简单的解决方法应该是拥有

.then( () => console.log( ...

【讨论】:

  • @SebastianSimon:我希望不是你因为找到了重复而对正确答案投了反对票。问候。
  • 我没有。只是想链接该帖子并建议关闭而不是回答。
  • @SebastianSimon:下次请在问题下投票结束,而不是在答案下发表评论。答案不能关闭,问题可以。
  • 我还没有足够的信心在这里投票,因为我想确保这确实是 OP 代码中唯一的问题。 有足够的信心发布答案……
【解决方案2】:

为此,您需要等待display_modal 的回复。

async function display_modal(title, message, button_label = "Accept") {
  // resolve promise when accept is clicked
  return new Promise((resolve) => {

    // create a modal from template
    const temp = document.querySelector("#modal_template");
    let clone = temp.content.cloneNode(true);
    clone.querySelector(".modal_header").innerText = title;
    clone.querySelector(".modal_message").innerText = message;

    // create an accept button
    const button = clone.querySelector(".modal_accept_button");
    button.innerText = button_label;
    button.addEventListener("click", (e) => {
      // On click, delete modal and resolve the promise
      const modal_background = e.srcElement.parentNode.parentNode;
      modal_background.parentNode.removeChild(modal_background);
      resolve();
    });

    document.body.appendChild(clone);
  });
}

window.onload = () => {
  const alert = document.querySelector(".alert");
  alert.addEventListener("click", async() => {
    await display_modal("Alert", "Important message", "Accept");
    console.log("Accept button clicked");
  });
}
* {
  background-color: #333;
}

.modal_background {
  position: fixed;
  z-index: 2;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: auto;
  background-color: rgba(0, 0, 0, 0.4);
}

.modal_content {
  background-color: #222;
  max-height: calc(100vh - 100px);
  padding: 20px;
  margin: 20px auto;
  width: 80%;
}
<!DOCTYPE html>
<html lang="en">

<head>
</head>

<body>
  <button class="alert">Do stuff</button>
</body>

<template id="modal_template">
    <div class="modal_background">
        <div class="modal_content">
            <h2 class="modal_header"></h2>
            <p class="modal_message"></p>
            <button class="modal_button modal_accept_button"></button>
        </div>
    </div>
</template>

</html>

【讨论】:

    猜你喜欢
    • 2021-01-24
    • 2022-01-22
    • 2015-03-24
    • 2022-12-05
    • 2016-12-13
    • 2018-07-29
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    相关资源
    最近更新 更多