代码之家  ›  专栏  ›  技术社区  ›  CrazySynthax

如何使异步事件处理程序按特定顺序工作?

  •  2
  • CrazySynthax  · 技术社区  · 8 年前

    假设我有一个带有事件处理程序的按钮:

    <button onclick="btnClicked()"> CLICK ME </button>
    

    这是js文件:

    var num = 0; // global variable
    
    function btnClicked() { 
       num++;
       console.log(num);
    }
    

    但是,这不是我将得到的。每次点击按钮都会调用该功能 btnClicked BTN已单击 ,通过该行 num++ 然后(出于某种原因)保持不变。同时,第二次调用进入num=1的函数,将其递增为2,在控制台中打印2,然后第一次调用继续执行num=2,因此也打印2。

    4 回复  |  直到 5 年前
        1
  •  1
  •   CrazySynthax    8 年前

    阅读了回复后,我明白了我描述的场景(控制台将打印“2”两次)是不可能的。

    function btnClicked() { 
       num++;
       console.log(num);
       **AJAX call** 
    }
    

    那么执行顺序将是: 为第一次调用发送的AJAX调用 打印2

    在这种情况下,两个AJAX调用都发生在不同的线程中,我们无法确定哪一个将首先结束。

        2
  •  0
  •   user2446768    8 年前

        3
  •  0
  •   Frish    8 年前

    虽然它可能无法直接解决您的问题,但建议使用 eventListener

    此外,要使变量成为全局变量,您可以在不使用“var”的情况下对其进行调用——这可能并不完全是您希望使用“num”之类的泛型来实现的,但这将使其成为全局变量(更多信息) here ).

    <button id='click-me'> CLICK ME </button>
    
    <script>
        num = 0; // global variable
        document.getElementById('click-me').addEventListener('click', function(){
            // function here
        });
    </script>
    
        4
  •  0
  •   Alex Nikulin    8 年前

    你只需要承诺解决订单问题。

    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>