回调和异步

64 阅读1分钟

异步,即不等结果,如在排餐厅的号的时候顺便去逛逛附近

同步,即等结果,如在排餐厅的号的时候一直在那排

下面是一个同步代码的示例

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) => {
            // ...
          }
        })
      }
    })
  }
})