JavaScript 基础
Document
运算符
深入数据和类型
函数进阶
原型、继承
类
浏览器存储
Web API
事件
错误处理
异步编程
网络请求
模块
练习
实例
工具与规范
软件架构模式
设计模式
异步
在 JavaScript 中很多执行不是立刻进行的,比如读取个文件、加载网络URL、DOM操作等等,执行这些不是立刻执行,且稍后才能得到结果的就是 异步执行
。与之相对的,立刻执行并能得到结果的就是同步执行
。
$$tip
你可以发现,异步执行的函数基本都是耗时长的函数,比如读取文件或加载网络 URL。设想一下,如果这些是同步执行,那么将会阻塞我们 JavaScript 进程, 那么之后的代码都得等待执行完成,会造成页面卡死。
$$
常用的 setTimeout
也是典型的异步函数:
console.log("开始执行") // 同步执行
setTimeout(() => console.log("大家好"), 3000) // 异步执行
console.log("结束执行") // 同步执行
// 最终结果
// 开始执行
// 结束执行
// 大家好
回调
使用异步执行就有个问题了,我们不知道执行有没有完成,有没有成功,执行结果也不得而知。
$$jsdemo$$
$$edit$$
function loadFile() {
// 读取文件需要三秒钟
setTimeout(function () {
const file = "文件内容"
console.log(file)
return file // 外部无法获取返回的 file
}, 3000)
}
console.log("开始执行") // 同步执行
const file = loadFile() // 无法得到执行结果
console.log(`文件内容:${file}`) // 文件内容:undefined
console.log("结束执行") // 同步执行
为了解决这个问题,我们想出了一种方法。传递一个函数,使得调用方在函数执行结束时调用,并传递执行结果。这种方式就被称为回调,而执行结束时调用的函数就被称为回调函数。
$$jsdemo$$
$$edit$$
function loadFile(callback) {
// 读取文件需要三秒钟
setTimeout(function () {
const file = "三眼鸭的编程教室"
// 将结果作为参数传到回调中
callback(file)
}, 3000)
}
console.log("开始执行") // 同步执行
loadFile(function (file) {
// 得到执行结果
console.log(`文件内容:${file}`) // 文件内容:三眼鸭的编程教室
})
console.log("结束执行") // 同步执行