测理论--异步与回调的关联和区别

简介: 异步与回调的关联和区别

一、异步


如果能直接拿到结果就是同步。

比如:你在医院挂号。任务是拿到号,你只有拿到号,你才会离开

如果不能直接拿到结果就是异步。

比如:网红餐厅排队吃饭,人很多,你的任务是吃饭,只有吃到饭才能离开,那么如果排队人很多,比如给你了一个100号,前面有99人等待,那么你是不是就可以再等待的时候去逛街或者做别的。你可以在这个时间每10分钟去餐厅问一下到你没有(轮询),也可以用手机微信扫码接受通知(回调),知道你吃上饭。

在异AJXA为例,其实request.send()之后,并不能能直接拿到结果,不信可以console.log(request.response)试试,必须等到readyState变成4后,浏览器回头调用request.onreadystatechange函数才可以。


二、回调callback


回调函数是异步操作最基本的方法。简单来说,回调就是自己写了却不调用,给别人调用的函数


代码实例


function f1(){}
function f2(fn){
    fn()
}
f2(f1)


代码1:函数2调用函数1


  1. f1函数被声明,却没有被调用
  2. f1函数当成参数传给f2函数,
  3. f2函数调用了f1函数,所以f1是回调
function f1(x){
    console.log(x)
}
function f2(fn){
    fn('你好')
}
f2(f1)


代码2:


fn('你好')中的fn就是f1, fn('你好')中的你好会被赋值给参数x

那么思考一下最后的结果是打印出你好,你好来自于哪里,是不是f2调用并且给f1传递了一个参数,那么问下f2的运行结果是什么?(参数)


三、异步与回调的关系


关联


异步任务需要在得到结果时通知JS来读取结果。等待通知的过程就是异步,通知JS读取结果的过程就是回调。

具体实现就是让JS编写留下函数地址给浏览器(留下电话号码),异步完成后浏览器调用该函数地址(拨打电话),同时把参数传给该函数(打电话通知顾客取那桌就餐),这个函数是用户写给浏览器调用的,所以是回调函数


区别


异步任务需要用到回调函数来通知结果

回调函数却不一定存在于异步任务中,同步任务中也可以用到回调函数,

例如array.forEach(n=>{console.log(n)}),其中n=>{console.log(n)}就是回调函数


四、如何判断是同步还是异步


异步


如果一个函数的返回值处于如下三种情况就是异步(暂时直说三种)

  • setTimeout
  • AJAX (即XMLHttpRequest)
  • AddEventListener

如果一个函数在这三个内部,就是异步

注意:AJAX也可以设置为同步的,例如在request.open("get", "/style.css", false)添加false。但是在请求期间会让页面卡住,阻止用户其他操作。因此, 异步才是最佳选择。


五、摇骰子例子


例子总结(提前说)

异步任务不能拿到结果,所以需要传一个回调给异步任务。

异步任务完成时调用回调,调用的时候把结果作为参数传给回调函数


第一步


function 摇骰子(){  // 异步函数    
 setTimeout(()=>{     
  return parseInt(Math.random()*6)+1
 },1000)  
 //return undefined 
}  
const n = 摇骰子()
console.log(n) // undefined

摇骰子()没有写return,所以返回return undefined箭头函数返回真正的结果


第二步


function f1(x){console.log(x)} 
function 摇骰子(fn){    
// 异步函数     
setTimeout(()=>{ 
fn(parseInt(Math.random()*6)+1)
 },1000)   
//return undefined 
}  
摇骰子(f1)

怎样拿到异步的结果?

使用回调。

首先声明函数,然后把函数地址传给摇骰子(), 然后摇骰子()得到结果后把结果作为参数传给f1()


第三步(代码简化)


function f1(x){console.log(x)} 
摇骰子(f1)
//简化1
摇骰子( x=>{console.log(x)}) 
 // 简化 2
摇骰子(console.log)//最简

注意,如果参数个数不一致,就不能这样简化到最后一步。函数中一个参数x和一个执行参数x是一致的,简化成功。

例子

// 输入错误结果,简化失败
const array = ['1','2','3']
array.map(parseInt) //  [1, NaN, NaN]
// 正确运行
const array = ['1','2','3']
array.map((item, i, array) =>{
    return parseInt(item)
}


六、回调的弊端


1、在处理回调时代码不够规范,命名不规范

2、容易出现回调地狱

3、很难进行错误处理

目录
相关文章
|
6月前
|
Java Android开发
Android系统 获取用户最后操作时间回调实现和原理分析
Android系统 获取用户最后操作时间回调实现和原理分析
195 0
|
1月前
|
前端开发 Java API
vertx学习总结5之回调函数及其限制,如网关/边缘服务示例所示未来和承诺——链接异步操作的简单模型响应式扩展——一个更强大的模型,特别适合组合异步事件流Kotlin协程
本文是Vert.x学习系列的第五部分,讨论了回调函数的限制、Future和Promise在异步操作中的应用、响应式扩展以及Kotlin协程,并通过示例代码展示了如何在Vert.x中使用这些异步编程模式。
49 5
vertx学习总结5之回调函数及其限制,如网关/边缘服务示例所示未来和承诺——链接异步操作的简单模型响应式扩展——一个更强大的模型,特别适合组合异步事件流Kotlin协程
|
存储 安全 编译器
大师学SwiftUI第9章Part 2 - 异步并发之Actor、异步序列、任务组和异步图像
异步任务对于希望释放资源让系统可以执行其它任务的场景非常有用,比如更新界面,但在希望同步执行两个任务时,就需要用到并发。为此,Swift标准库定义了async let语句。
107 2
大师学SwiftUI第9章Part 2 - 异步并发之Actor、异步序列、任务组和异步图像
|
前端开发
前端学习案例2-this.setstate是同步和异步2 原
前端学习案例2-this.setstate是同步和异步2 原
62 0
前端学习案例2-this.setstate是同步和异步2 原
第十二章队列模拟注意事项
第十二章队列模拟注意事项
58 0
异步思维——把请求与解析分开
异步思维——把请求与解析分开
63 0
HIMA F3 DIO 8/8 01 控制动作依赖于来自过程的反馈
HIMA F3 DIO 8/8 01 控制动作依赖于来自过程的反馈
HIMA F3 DIO 8/8 01 控制动作依赖于来自过程的反馈
|
JavaScript
浅谈同步、异步、回调函数之间的关系?
同步:发出一个调用时,在没有得到结果之前,该调用就不返回;一旦调用返回,就得到返回值。换句话说,就是由调用者主动等待这个调用的结果。
605 0
|
JSON 测试技术 数据格式
软件测试面试题:依赖于登录的接口如何处理?
软件测试面试题:依赖于登录的接口如何处理?
318 0
|
前端开发
前端工作总结263-判断绑定逻辑
前端工作总结263-判断绑定逻辑
53 0
下一篇
无影云桌面