异步和回调

139 阅读2分钟

异步

异步指一种函数,一种任务,这种函数不会立刻得到结果,而得到结果之前不妨碍去执行其他JS代码.例如settimeout(),addEventListener(),AJAX(XMLre),如果函数的返回值处于这三种代码内部一般都是异步的任务.除了AJAX可以设置参数为同步,但不会有人这么做.

回调

回调指当你创建了一个函数,而不由自己主动去调用,而是让函数让浏览器调用,那么这种函数就叫做回调函数.事实上你只要把函数一作为参数丢进另一个函数二调用时,那么函数一就是一个回调函数,不然你丢进去干什么.

异步+回调

异步函数把将结果作为参数回调函数

注意:如果异步的结果和回调函数的形参数量不匹配,可能会造成错误,例如

[1,2,3].map(parsenInt)
结果是[1,NAN,NAN]

原因是array.map()有三个结果分别是:item,index,array.而parsenInt默认的形参有两个,分别是数字和指定转化的进制数

两个结果两个回调函数

异步不但可能有两个结果,而且这两个结果还要分别回调一个函数,那么怎么满足呢?有两种方法

  • 把回调函数改造成兼容两个结果的函数,接受两个参数还要自己动手改造函数,这种方法难用
  • 直接传两个函数或者传一个对象,对象上挂两个方法

上面的两种方法实现了需求,但是有优缺点:

  • 代码不规范
  • 容易造成回调地狱
  • 难以处理错误

promise

异步返回Promise构造出的对象,这个对象的then方法调用两个函数

ajax = (method, url, options)=>{
  return new Promise((resolve, reject)=>{
    const {success, fail} = options
    const request = new XMLHttpRequest()
    request.open(method, url)
    request.onreadystatechange = ()=>{
      if(request.readyState === 4){
        // 成功就调用 resolve,失败就调用 reject
        if(request.status < 400){
          resolve.call(null, request.response)
        }else if(request.status >= 400){
          reject.call(null, request)
        }
      }
    }
    request.send()
  })
}

ajax('get', '/xxx')
  .then((response)=>{}, (request)=>{})

axios

这样的Ajax函数不能给send()传参数,不能设置请求头,所以使用axios,封装好的Ajax库