AJAX(2)异步

307 阅读4分钟

经过昨天的一天AJAX的学习,今天对AJAX的起手写法已经烂熟于心了,那么现在开始新的AJAX的学习

异步

什么是异步?对它我的理解是,如果能直接拿到结果的,就是同步,如果不能直接拿到结果的,就是异步。

  • 我们可以举个例子

比如我们去医院看病,往往需要先挂号,挂号这个操作是每次看病必不可少的,所以只能规规矩矩的跟着队伍挂号,这个就是同步的。但是当挂完号之后,什么时候去看病,是按照你挂号的号码来的,可能立刻就能看,可能要好久才能看,这个就是异步的,我无法立刻进行挂号的操作。

对于异步的这个操作,我们可以有两种操作的方法:回调和轮询,还是用举例来说:

对于回调,就是我们用微信接收通知,等到我们了手机会通知我们回去,对于轮询,就是我们自己人每过几分钟过去看一看,到我们了没有

异步用在AJAX

在AJAX中,我们在request.send之后,并不能直接得到response,必须等到readyState变成4之后,通过回调函数onreadstatechange,我们才能得到request,这就是一个异步操作用回调函数解决的案例

  • 异步和回调的关系

异步任务需要在得到结果时通知JS来拿结果,怎么通知?可以让JS写一个函数给浏览器,异步任务完成时就调用这个函数,此时就能把结果作为参数传给函数。因为这个函数写出来是在别的方法执行完之后才进行的调用,所以这个函数是回调函数。

  • 区别

异步需要回调函数来通知结果,但是回调不一定要用在异步内,比如forEach((a)=>{a += 1})

  • 判断同步异步
    • setTimeOut
    • AJAX
    • AddEventListener
    • Promise.then 以上几个全是异步的,其他没说的都是同步的(还有好多,一下子想不起来了,具体情况具体分析)
      通过回调来写一个摇骰子
function f1(x){
	console.log(x)
}
function 摇骰子(fn){
	setTimeOut(()=>{
   	fn(Math.random()*6+1)
   },1000)
   
这个代码还可以简化
摇骰子(console.log)

此时,f1就是个回调函数,用来获得摇骰子方法中的值。
总结一下:

  • 异步任务不能拿到结果
  • 于是我们写一个回调给异步任务
  • 异步任务完成时调用回调
  • 调用的时候把结果作为参数传给回调
  • 回调执行,将结果处理后返回

回调的参数过多

如果回调的参数不止一个,比如有两个,此时我应该怎么办?
那就搞两个回调fn(参数1=>{},参数2=>{}),或者接收两个参数,fn((参数1,参数2)=>{}),此时就会出现各种各样的解决方法,有人用第一种,有人用第二种。 而且过多的回调,会导致出现回调地狱,此时代码就变得十分难懂

getA(a=>{
	getB(a,b=>{
    	    b.forEach((c)=>{
        	   c.map((x)=>{
            	     x.id = a}).forEach((x)=>{x++})	
        })
    })
})

这就是成堆的回调造成的回调地狱,这样很难进行错误的处理。 于是就有人抄袭了Promise,用Promise来解决这个问题,Promise到时候会再次做出一个总结,这边只给出封装的结果

ajax = (url,fn1,fn2)=>{
	return new Promise((resolve,reject)=>{
	const request = new XMLHttpRequest();
    request.open('get',url)
    request.send()
    request.onreadystatechange = ()=>{
    if (request.readyState === 4){
        if (request.status >= 200 && request.status < 300){
            resolve.call(null,request.response)
        }else{
            reject.call(null,request)
        }
    }
  }.then((e)=>{
      fn1()
  },(e)=>{
      fn2()
  })
}

因为Promise的then返回一个Promise对象,所以可以链式调用,如果还要接着在上一个结果中调用函数,直接一个接下去用then就好了,非常的方便。但是这个封装还是很有问题的:我们无法指定请求头,比如说应对同源策略的的CORS。于是针对上述的问题,我们想到了运用库去解决——比如JQuery的ajax,以及现在常用的axios。jQuery的库现在已经很少前端在使用了,主要用的就是axios,所以我们这也开始直接用axios来解决问题。 axios的使用有点长,回头单独写一篇文章介绍吧