为何按下回车键会触发resolve,解除JavaScript的await等待?
按下回车键触发resolve解除await等待的原因及修复方案
问题现象
点击按钮执行fnresolve()可以正常解除await的等待,但按下回车键时,也会触发resolve并解除等待,这是怎么回事?
原代码如下:
<html> <head> <title> Q:await </title> <meta charset="utf-8"> <script> "use strict"; let fnresolve, n=0; // globals window.onload = function() { zlog('Hit the button, then the ENTER key'); zlog(); Main(); } async function Main() { do { zlog('before wait', ++n); let pMain = new Promise((res) => { fnresolve = res; } ); // save the res function await pMain; zlog('after wait', n); zlog(''); } while (1); } function zlog() { document.getElementById('zlog').innerHTML += (Object.values(arguments).join(', ')) + '<br />'; } </script> </head> <body> <button onclick='fnresolve();'> fnresolve </button> <div id='zlog'></div> </body> </html>
原因分析
这是浏览器的默认行为导致的:当按钮获得焦点时,按下回车键会触发按钮的click事件。点击按钮后,按钮会自动获取焦点,此时按下回车键,浏览器就会模拟执行按钮的点击逻辑,调用fnresolve(),进而触发Promise的resolve,解除await的等待状态。
修复方案
在按钮的onclick事件中添加this.blur(),让按钮点击后立即失去焦点:
<button onclick='fnresolve();this.blur();'> fnresolve </button>
修复原理
this.blur()会移除按钮的焦点,这样后续按下回车键时,因为按钮不再处于聚焦状态,浏览器就不会触发它的click事件,也就不会意外调用fnresolve()了。
内容的提问来源于stack exchange,提问作者dcromley
相关产品推荐
相关产品推荐

