假设我有一个带有事件处理程序的按钮:
<button onclick="btnClicked()"> CLICK ME </button>
这是JS文件:
var num = 0; // global variable
function btnClicked() {
num++;
console.log(num);
}
假设我在同一按钮上单击了两次。我希望在控制台1和2中看到。
,但是,这是我所能得到的。每个按钮单击都会使函数 btnClicked
异步调节,因此有可能在第一个呼叫结束之前结束第二个呼叫的情况。例如第一个调用调用btnClicked
,通过线num++
,然后(由于某种原因)。同时,第二个调用输入了num = 1,将其递增到2,在控制台中打印2的函数,然后第一个调用继续使用num = 2继续执行,因此也打印2。
您知道只有在第一次调用结束之后才能确保第二次调用会发生吗?
阅读了我知道我所描述的场景(控制台将两次打印的场景)是不可能的。
事件处理程序被添加到事件队列中。事件队列不是V8线程。因此,事件队列中的每个任务都将同步执行,即仅在第一个调用结束后,第二个任务才会启动。
但是,如果该功能为:
function btnClicked() {
num++;
console.log(num);
**AJAX call**
}
然后执行令是:印刷:1Ajax电话发送了首次调用打印2Ajax调用发送第二个调用
,在这种情况下,两个Ajax调用都在不同的线程中进行,我们无法确定其中哪一个将首先结束。
在按钮上单击"只需禁用按钮,并且在函数的末尾启用按钮。你能尝试一下吗?我认为它将对您有用。
虽然可能无法直接解决您的问题,但建议使用EventListener而不是OnClick。
另外,要制作一个变量全局,您会在没有" var"的情况下称其为" var" - 也许不完全是您要使用诸如'num'之类的通用事物来做的事情,但这会成为全局(在这里详细介绍)。
这将为您提供类似的东西:
<button id='click-me'> CLICK ME </button>
<script>
num = 0; // global variable
document.getElementById('click-me').addEventListener('click', function(){
// function here
});
</script>
您只需要一个解决订单问题的承诺即可。每个事件都会每次进行。但是,如果您有AJAX请求,并且需要在您获得服务器响应后每个人都会通过每个请求发送。然后,您通过单击按钮发送AJAX请求(异步执行函数按某些顺序执行,每个订单每个订单)。因此,这是一个具有假执行功能的工作示例。
var num = 0;
var executing = new Promise(function(resolve, reject){
resolve();
});
var btnHandle = function(){
executing.then(createJobInstanse());
}
var createJobInstanse = function(){
return function(){
return new Promise(function(resolve, reject){
// fake asynchronous operation from 10ms to 2000ms, with random execution time
window.setTimeout(function(){
console.log(num++);
resolve();
}, Math.floor(Math.random() * 2000) + 10);
});
};
}
var btn = document.querySelector("#btn");
btn.addEventListener("click",btnHandle);
<button id="btn" onclick="btnHandle">click</button>