异步与Promise

异步与Promise(面试必考)

AJAX(Async JavaScript And XML)
内容:Ajax异步编程在js里的统一解决方案(js异步编程模型) Promise

什么是异步?什么是同步?

同步:能直接拿到结果
比如你在医院挂号,拿到号才会离开窗口。
同步任务可能消耗10ms,也可能需要3s
总之不拿到结果你是不会离开的

异步:不能直接拿到结果
比如你在餐厅门口等位,拿到号可以去逛街
什么时候才能真正吃饭呢?
你可以每10min去餐厅问一下(轮询)
你也可以扫码用微信接收通知(回调)
异步通常指"异步加回调"
举例
1.以ajax为例
request.send()之后,并不能直接得到response
不信console.log(request.response)试试
必须等到readState变为4后,浏览器回头调用
request.onreadystatechange函数
我们才能得到request.response
这跟餐厅给你发送微信提醒的过程是类似的

补充:在js中发一个网络请求并得到响应大概要几百ms~1/2s
在这里插入图片描述

getJSON.onclick = () => {
  ...
  request.send()
  console.log(request.response) //不能直接得到response
  setTimeout(() => { //2s后得到response
    console.log(request.response)
  }, 2000)
}
下载完成后浏览器会回调request.onreadystatechange函数
所以上面的代码等价于
 request.onreadystatechange = () => {
   if (request.readyState === 4 && request.status == 200) {
       console.log(request.response)
       ...
   }
打印出response后就是3s后

2.回调callback
你写给自己用的函数,不是回调
你写给别人用的函数,就是回调
request.onreadystatechange就是我写给浏览器调用
意思就是浏览器回头调一下这个函数
「回头」也有「将来」的意思,如「我回头请你吃饭」
举例
1.把函数1给另一个函数2

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

我调用f1没有?没有
我把f1传给f2了没有?传了
f2调用f1了没有?调了
那么f1是不是我写给f2调用的函数?是,所以f1是回调
没有调用、传给别人了、别人调用了
补充

//request.setCallback(onreadystatechange)
request.onreadystatechange

是不是参数这个问题并不大,直接写一样的效果
不过一般不推荐放到对象上,最好作为参数传给它,防止别人不知道

抬杠1,如果我传给f2的参数不是函数呢?
会报错:fn不是一个函数。看到报错你不就知错了
抬杠2

function f1(x){
  console,log(x)
}
function f2(fn){
  fn('你好')
}
f2(f1)

f1怎么会有一个x参数
fn(‘你好’)中的fn就是f1对吧
fn(‘你好’)中的’你好’会被赋值给参数x对吧
所以x就是’你好’。x表示第1个参数而已

异步和回调的关系

回调就是我把一个函数传给你 或者传到全局函数request上
关联
异步任务需要在得到结果时通知js来拿结果
怎么通知呢?
可以让js留一个函数地址(电话号码)给浏览器
异步任务完成时浏览器调用该函数地址即可(拨打电话)
同时把结果作为参数传给该函数(电话里说可以来吃了)
这个函数是我写给浏览器调用的,所以是回调函数
区别
异步任务常常用到回调函数来通知结果,但不一定非要用回调。也可以用轮循
回调函数也不一定只用在异步任务里,也可以用到同步任务里
array.forEach(n=>console.log(n))就是同步回调
array里有多少个元素forEach就会调用函数n多少次

判断同步异步

怎么区分一个函数是同步还是异步?
根据特征或文档
如果一个函数的返回值处于这3个东西内部,那么这个函数就是异步函数
setTimeout
Ajax(即XMLHttpRequest)
AddEventListener
等下,我听说Ajax可以设置为同步的
傻X前端才把Ajax设置为同步的,这样会使请求期间页面卡住。

例子:异步1个结果的处理
1s后返回1~6的随机数

function 摇骰子(){
    
  setTimeout(()=>{
    
    return parseInt(Math.random() * 6 ) + 1 
  },1000)
  //return undefined
}

const n=摇骰子()
console.log(n) //undefined

摇骰子()没有写return,那就是return undefined
箭头函数里有return,返回真正的结果
注意这2个return属于不同的函数
所以这是一个异步函数/任务

那怎么才能拿到异步结果(1~6的随机数)?
可以用回调。写个函数,然后把函数地址给它

function f1(x){console.log(x)}
摇骰子(f1)

然后我要求摇骰子函数得到结果后把结果作为参数传给f1

function 摇骰子(fn){
    
  setTimeout(()=>{
    
    fn(parseInt(Math.random() * 6 ) + 1) //得到结果后传给fn
  },1000)
}

将结果传给fn,这时候就能输出结果了。

简化为箭头函数。f1声明后只用了一次,所以可以删掉f1
优化技巧: 函数声明后只用了一次时,可以简化为匿名函数

function f1(x){
   console.log<
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老老老老李

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值