异步编程
JavaScript 默认情况下是同步且单线程的。 这意味着代码无法创建新的线程并且不能并行运行,而是依次执行的。
但是 JavaScript 一开始的主要工作就是响应用户的操作,例如onClick
、onChange
、onSubmit
、onMouseOver
等。
在程序运行中,当某些请求过程漫长,我们有时没必要选择等待请求完成继续处理下一个任务,这时使用回调函数进行异步处理可以大大提高程序执行效率。
回调
回调是一个简单的函数,会作为**值被传给另一个函数,并且仅在事件发生时才被执行**(在其父函数完成后执行)。
实际案例
点击事件回调函数:
$("#myBtn").click(function(){
alert("click myBtn!");
});
事件处理器:
document.getElementById('button').addEventListener('click', () => {
//被点击
})
以setTimeout为例
<p>回调函数等待 3 秒后执行。</p>
<p id="demo"></p>
<script>
setTimeout(function () {
document.getElementById("demo").innerHTML="执行了回调函数";
}, 3000);
</script>
这段程序中的 setTimeout
就是一个消耗时间较长(3 秒)的过程。它的第一个参数是个回调函数,第二个参数是毫秒数,这个函数执行之后会产生一个子线程,子线程会等待 3 秒,而后输出内容。
注意:
setTimeout
会在子线程中等待 3 秒,但在setTimeout
函数执行之后主线程不会停止。
setTimeout(function () {
console.log("1");
}, 1000);
console.log("2");
// 2
// 1
回调函数传参
两种回调函数传参的方法:
- 将回调函数的参数作为与回调函数同等级的参数进行传递 ```javascript // 回调函数需要一个参数value function say(value){ console.log(value); }
// 在函数后面加上()就是运行这个函数 // 参数在小括号()内传入 function execute(testFunction, value){ testFunction(value); }
// say方法就是回调函数,’hello’就是say方法所需要的参数 // 这里的’hello’与say同等级,一并传入 execute(say, ‘hello’);
- 回调函数的参数**在调用回调函数的主函数内部创建**
```javascript
// 回调函数的参数value在这里是一个对象,拥有name属性
function say(value){
console.log(value.name);
}
// 这里execute只接受一个参数,即say函数本身
function execute(testFunction){
let value = {
name: 'hello'
};
testFunction(value); // value参数传入testFunction,即回调传参
}
// say是回调函数,参数在execute函数内部定义
execute(say)
常见用途总结
- 异步调用
- 事件监听器/处理器
setTimeout
和setInterval
方法- 精简代码