Javascript 使用异步函数等待来自onclick的用户输入

Javascript 使用异步函数等待来自onclick的用户输入,javascript,callback,async-await,event-handling,dom-events,Javascript,Callback,Async Await,Event Handling,Dom Events,我不熟悉异步,可能只是不了解基本原理,但我试图通过调用一个异步函数来等待用户从onclick输入,该函数弹出一个模式并等待用户提交数据。在只找到一个或两个甚至提到使用异步等待页面事件的源之后,这些事件对我的特定任务没有特别的帮助。。。我想到了这个: asnyc func1 (){ var userInput = await async2(); //do stuff with user input } async func2(){ //build modal content spec

我不熟悉异步,可能只是不了解基本原理,但我试图通过调用一个异步函数来等待用户从onclick输入,该函数弹出一个模式并等待用户提交数据。在只找到一个或两个甚至提到使用异步等待页面事件的源之后,这些事件对我的特定任务没有特别的帮助。。。我想到了这个:

asnyc func1 (){
  var userInput = await async2();

  //do stuff with user input
}
async func2(){
  //build modal content specific to task
  //display modal
  return new Promise(function(resolve,reject){
       $(document).on('click', '#save-input', function(e){
          var input = $('#input-data').val();
          resolve(input);
      });
  });
}
所有调用似乎都正确,我得到了用户的输入,但func1在调用async2之后从未继续。所以很明显,我遗漏了一些关键的方面,但我似乎无法从我的来源中找到答案

回调不是一个选项,这里的代码比我简单地描述的要多得多,但上面描述的是我需要执行的基本功能。

Simple snippet
const timeout=async ms=>new Promise(res=>setTimeout(res,ms));
设next=false;//这将在用户输入时更改
异步函数waitUserInput(){
while(next==false)等待超时(50);//暂停脚本
next=false;//重置变量
}
使用jQuery的示例用法

//只需更改'next'的值,脚本即可继续
$(“#用户输入”)。单击(()=>next=true);
异步函数myFunc(){
//做事之前
等待waitUserInput();//等待用户单击
//事后做事
}
myFunc()//启动函数并开始等待用户输入
请查看此工作演示

//这是一个异步超时
const timeout=async ms=>new Promise(res=>setTimeout(res,ms));
设next=false;//这将在用户输入时更改
设n=1;
异步函数waitUserInput(){
while(next==false)等待超时(50);//暂停脚本,但避免浏览器冻结;)
next=false;//重置变量
}
异步函数myFunc(){
$('#text')。追加(`*等待用户输入…
`) 等待waitUserInput(); $('#text').append(`*用户已单击${n++}次
`) myFunc() } $(“#用户输入”)。单击(()=>next=true) myFunc()

点击我!

我搜索了很多,但什么也没找到,只有这个问题。 我想要一些不依赖循环检查的异步的东西,所以我做了一个不同的解决方案

主要问题是使用事件侦听器解决promisse,因此我在promisse中创建了eventListener函数,并使用arrow函数获取promisse的上下文。然后,在第一次单击后,我解析承诺并取消eventListener

为了使函数可用于任何侦听器,我也为此设置了一个条目

function waitListener(element, listenerName) {
    return new Promise(function (resolve, reject) {
        var listener = event => {
            element.removeEventListener(listenerName, listener);
            resolve(event);
        };
        element.addEventListener(listenerName, listener);
    });
}
如果您想将事件用于某些用途,它将返回该事件。 这使您更容易以有序的方式编写一些代码序列。但要工作,它必须在异步函数中,这意味着该函数将开始并行运行,因此知道要从何处开始非常重要,以免妨碍进程

在某些异步函数中的简单用法:

var element = document.querySelector("button");
await waitListener(element,"click");
完整样本:

函数waitListener(元素,ListenerName){
返回新承诺(功能(解决、拒绝){
var listener=event=>{
元素。removeEventListener(ListenerName,listener);
解决(事件);
};
元素。addEventListener(ListenerName,listener);
});
}
异步函数(){
var元素=document.querySelector(“按钮”);
等待waitListener(元素“单击”)
//做第一件事
.然后(e=>{
日志(“e.clientX:+e.clientX”);
});
控制台日志(1);
等待waitListener(元素“单击”);
//做第二件事
控制台日志(2);
等待waitListener(元素“单击”);
//做第三件事
控制台日志(3);
}
等待点击()

单击
在我看来很好。你能提供一个更接近你的实际代码吗?请注意,你应该使用
一次而不是
上的
,因为承诺只能解决一次,并且在那之后会自动删除处理程序。我会尽快添加一个,这两个函数都是匿名对象成员函数,会有什么区别吗?和/或如果我在
var input=
发生之前调用另外两个函数,会有什么不同吗?想知道我是否需要对解决的每一个问题进行等待,我意识到代码的另一部分是提前调用func2,并导致承诺在错误的情况下返回,扰乱了流程,因此当我真的想等待承诺时……它已经解决了。在这种情况下,您可能希望删除您的问题这只允许用户单击按钮两次。如果您希望按钮在单击时始终工作,该怎么办?看看这个答案。