使用 setTimeout 绑定事件以创建自定义异步回调

Binding events with setTimeout to create custom asynchronous callbacks

花时间阅读答案 here,这有助于我更好地理解 JavaScript 的异步性质。我还在弄湿我的脚。我试图通过绑定 setTimeouts 到不同的事件来创建我自己的回调。具体来说 changeclick。我显然错过了一些东西。当我 select 一年时,我在控制台中出现以下错误。有什么帮助吗?谢谢!

html

<select id="select_year">
<option value="2021">2021</option>
<option value="2022">2022</option>
<option value="2023">2023</option>
</select>

js

function selectYear(selectedYear) {

$(document).on('change','#select_year',setTimeout(function() {

selectedYear = $(this).val();

}, 0),

)}


selectYear(function(year) {
console.log(year);
});

控制台出错

Uncaught TypeError: t.nodeName is undefined
    val jQuery
    selectYear http://localhost:8080/js/calendar.js:20
    setTimeout handler*selectYear http://localhost:8080/js/calendar.js:18
    <anonymous> http://localhost:8080/js/calendar.js:25
jquery.min.js:2:69132
    val jQuery
    selectYear http://localhost:8080/js/calendar.js:20
    (Async: setTimeout handler)
    selectYear http://localhost:8080/js/calendar.js:18
    <anonymous> http://localhost:8080/js/calendar.js:25

执行您在此处执行的操作不需要 setTimeout。事件驱动编程本质上是异步的。试试这个:

'use strict'

const selectYear = year => {
  alert(year);
}

$('#select_year').on('change', function () {
    // This is your callback.
    let selectedYear = $(this).val();
    selectYear(selectedYear);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="select_year">
  <option value="2021">2021</option>
  <option value="2022">2022</option>
  <option value="2023">2023</option>
</select>

I'm clearly missing something.

没错!我什至会说很多事情

在谈论 asynchrounous 函数时,我们通常指的是稍后解析的函数调用,而不是阻止脚本执行的其余部分。如果您想了解,请查找 promise

你在提供的代码中做错了什么:

jQuery .on() 是一个事件处理方法。您可以传递 3 个参数:

  • 事件(强制)
  • 委托选择器(可选)
  • 回调(强制)

在这种情况下,回调是一个在事件触发时执行的函数。这与 asynchonous 函数不同。 What is an event?

在您的尝试中,您没有传递函数表达式或函数引用...而是函数 调用。如果你想在事件触发时执行 setTimeout,你必须将它放在如下函数语句中:

$(document).on('change','#select_year', function(){

  let selectedYear = $(this).val();
  
  setTimeout(function() {
    console.log(selectedYear);
  }, 2000);  // Try with 2 seconds to see the effect!
  
})

所以第三个参数是一个函数语句...存储以备后用。如果不清楚,here 就是您需要的读数。

另一件事... setTimeout() 的第二个参数是必需的数字。你用了零。这在某些情况下可能是正确的,但在这里不是。在第一个参数(顺便说一下,它是一个回调)执行之前,你应该使用一个数字来表示你想要多少毫秒的延迟。