异步,即不等结果,如在排餐厅的号的时候顺便去逛逛附近
同步,即等结果,如在排餐厅的号的时候一直在那排
下面是一个同步代码的示例
const ysz = () => {
const t = new Date() //先设置一个时间
while(new Date() - t < 3000){ //当t过了三秒之后
}
const n = Math.floor(Math.random() * 6) + 1 //随机摇一个数
console.log(`你得到的点数是${n}`);
return n
}
console.log(1); //打印1
const result = ysz() //三秒后打印 n
console.log(2); //打印2
上面代码按顺序执行,会打印出1 n 2
把上面代码改成异步的
const ysz = () => {
setTimeout(() => {
const n = Math.floor(Math.random() * 6) + 1
console.log(`你得到的点数是${n}`);
return n
}, 3000) //放进任务队列,三秒后执行,在此期间同步执行其它函数
}
console.log(1);
const result = ysz()
console.log(2);
异步代码的执行结果是:1 2 n
但是异步的ysz 并没有 return 因此拿不到结果
- 什么是异步?
如果执行了一个函数,却不等待函数返回结果,那么则称为异步执行了一个函数,或者说 执行了一个异步函数。
含有 setTimeout/queueMicrotask/AJAX 的函数,很有可能是异步函数(但不都是
如何获取异步——轮询或回调
- 轮询,即每过几秒就查看一遍变量
代码示例:
let m = -1 //创建全局变量
const ysz = () => {
setTimeout(() => {
const n = Math.floor(Math.random() * 6) + 1
console.log(`你得到的点数是${n}`);
m = n //赋值给全局变量
}, 3000)
}
console.log(1);
const result = ysz()
setInterval(() => {
if(m !== -1){
console.log(m);
}
}, 1000) //每过一秒查询一次
console.log(2);
- 回调,即把函数作为参数传给函数
代码示例:
const ysz = (success) => {
setTimeout(() => {
const n = Math.floor(Math.random() * 6) + 1
console.log(`你得到的点数是${n}`);
success(n) //调用success函数,接收变量
}, 3000)
}
console.log(1);
const success = (n) => console.log(n); //声明 success 函数,接收变量并打印
const result = ysz(success) //把success函数作为参数传入ysz函数中
console.log(2);
如果函数 A 的参数是函数 B,则称函数 B 为回调函数,称调用 B 为回调 B
回调函数是一种特殊的函数,回调是一种特殊的调用
button.onclick = fn
button.addEventListener('click', fn)
ajax({method:'get', url:'/x', success: fn})
这些,都是回调函数
回调地狱
即在回调中不断嵌套回调,套娃,如:
ajax({
method: 'get',
url: '/xxx',
success: (responseText) => {
ajax({
method: 'get',
url: `/${responseText}`,
success: (responseText) => {
ajax({
method: 'get',
url: `/${responseText}`,
success: (responseText) => {
// ...
}
})
}
})
}
})