推迟回调直到事件的最佳方法

时间:2017-11-16 05:25:25

标签: javascript callback queue

如果我们需要在某些情况下推迟回调并在事件发生时稍后调用,您会建议什么? 目前有几个排队模块,但我没有找到一个满足这个要求的要求。我的意思是,在完成任务之前,不要将任务从队列中运行。您可以在有合适的参数值或回调时运行它们。例如,

<html>
<body>
<input type="text" id="id1">
<input type="text" id="id2">
<script type="text/javascript">
    document.getElementById("id1")
        .addEventListener("keydown", function (e) {
            if (e.keyCode === 13) {
                upper(e.target.value);
            }
        });

    document.getElementById("id2")
        .addEventListener("keydown", function (e) {
            if (e.keyCode === 13) {
                delayed(e.target.value);
            }
        });

    function upper(x){
        if (parseInt(x) == x) {
            next_level(x, function(y){
                alert(y);
            });
        } else {
                alert('not int');
        }
    }

    function next_level(x, callback){
        y = Math.random() * 10;
        if (y < x){
            callback(y);
        } else {
            // postpone callback till y comes from id2 
            // put it into a queue
        }
    }

    function delayed(y){
        // take 1st element/callback from the queue
        // call it with y
        // if queue is empty, do nothing  
    }
</script>
</body>
</html>

2 个答案:

答案 0 :(得分:0)

<强> EDITED

我编辑了代码。这与您的代码示例更相似,但我仍然不确定我究竟理解了所期望的行为。如果这是错误的,请告诉我。

document.getElementById("id1")
  .addEventListener("keydown", function (e) {
    if (e.keyCode === 13) {
      upper(e.target.value);
    }
  });

document.getElementById("id2")
  .addEventListener("keydown", function (e) {
    if (e.keyCode === 13) {
      delayed(e.target.value);
    }
  });

function upper(x){
  if (parseInt(x) == x) {
    next_level(x, function(y){
      console.log(y);
    });
  } else {
    console.log('not int');
  }
}

const queue = [];

function next_level(x, callback){
  var y = Math.floor(Math.random() * 10);
  if (y < x){
    callback(y);
  } else {
    queue.push(callback);
    // postpone callback till y comes from id2 
    // put it into a queue
  }
}

function delayed(y){
  if (queue.length > 0) {
    const cb = queue.shift();
    cb(y);
  }
}
<input type="text" id="id1" />
<input type="text" id="id2" />

答案 1 :(得分:0)

请检查我的jsFiddle。它类似于amcdrmtt的答案,我试图在代码中解释发生了什么。

function next_level(x, callback){
  y = Math.random() * 10;
  if (y < x){
    callback(y);
  } else {
    // postpone callback till y comes from id2 
    // put it into a queue
    addToQueue(callback);
  }
}
// queue for callback methods
var queue = [];

// remember the callback for later
function addToQueue(func){
   queue.push(func); // add a method that calls func with the original arguments
    outputDiv.innerHTML += "<div>callback added to queue. queue length:" + queue.length + "</div>";
}
// call the last callback with a new value y
function delayed(y){
   // if queue is empty, do nothing
   if (queue.length === 0) {
    return;
   }
  // take 1st element/callback from the queue
  var firstCallback = queue.shift(); // also remove it from the queue
  // call it with y

  firstCallback(y);
}

https://jsfiddle.net/7pfzvL0d/4/