【问题标题】:the best way to postpone callback till event将回调推迟到事件的最佳方法
【发布时间】:2017-11-16 05:25:25
【问题描述】:

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

<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>

【问题讨论】:

  • 你能解释一下这对你意味着什么:“当有合适的参数值时”?另一种情况会是什么。什么是“不合适”的值?以及如何检查差异?
  • if (y &lt; x) 在这种情况下我们立即调用回调,否则我们正在等待事件(值将来自其他来源)。好吧,在真实情况下当然y 不是随机数,有一种复杂的方法可以得到它,但是对于演示采用随机 y 并将其与x 进行比较应该没问题

标签: javascript callback queue


【解决方案1】:

已编辑

我已经编辑了代码。这与您的代码示例更相似,但我仍然不确定我是否完全理解所需的行为。如果这是错误的,请告诉我 cmets。

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" />

【讨论】:

  • 感谢您的回复,但您误解了问题。我需要某种排队来累积回调,以防我们不幸运地在第一次运行时通过它。可能有很多不幸的案例(我们没有得到我们预期的数字),我们需要保留它们。此后发生一个事件,号码从不同的来源出现,现在我们可以从队列中调用第一个回调。一旦我们得到另一个数字,下一个队列元素就会出来。
  • 你能不能尽快写一个有效的例子?我不确定我是否完全理解您的要求。
  • 上面给出的例子。问题是我们只收到y &lt; x 的警报,而我们应该收到任何x 的警报。对于y &gt;= x,它们只是被推迟到id2 将获得一个值
  • 我已经编辑了我的示例。让我知道这是否是您正在寻找的更多内容。
【解决方案2】:

请检查我的 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/

【讨论】:

    猜你喜欢
    • 2012-04-14
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 2017-03-27
    • 2011-08-20
    • 1970-01-01
    相关资源
    最近更新 更多