7-4 前后分离(Promise、axios)

二、Promise

  • 如果异步任务有两个结果,成功或失败,怎么办?

1.两个结果怎么办?

  • 方法一:回调接受两个参数
    约定:每一个回调第一个参数是失败的error,第二个参数是成功的结果
fs.readFile('./1.txt',(error,data)=>{//读本地文件
  if(error){ console.log('失败');return }
  console.log(data.toString())//成功
})
  • 方法二:搞两个回调
  1. 前面函数是成功回调,后面函数是失败回调
ajax('get','/1.json',data=>{},error=>{})
  1. 接受一个对象,对象有两个key表示成功和失败
    回调不一定要用函数,还有可能是对象
ajax('get','/1.json',{
  success:()=>{},fail:()=>{}
})

2.以上方法的不足(记下来,表现promise更好)

  • 不规范,名称只是随便的约定而已,五花八门。
    有人用 success + error,有人用 success + fail,有人用 done + fail,
  • 容易出现回调地狱,代码变得看不懂
  • 很难进行错误处理

2.1 回调地狱

  • Node.js应用里面回调地狱非常常见
  • 因为Node.js默认的API全是异步的
  • 波动拳(Hadoken)
    在这里插入图片描述

3.解决问题

  • 规范回调的名字或顺序
  • 拒绝回调地狱,让代码可读性更强
  • 很方便捕获错误

4.以AJAX的封装为例
来解释Promise的用法

4.1 原始调用方法
在这里插入图片描述

  • ajax接收:两个参数和一个回调
    其中 options 是回调
  • 析构赋值:const { success, fail } = options
    意思是从options里拿出success和fail两个回调
    等价于:
const success = options.success 
const fail = options.fail 
  • 封装函数调用ES6简写为:
    左边的success是 funciton 缩写(success后省略了冒号和function),右边的fail是箭头函数
//封装函数定义:略
ajax('get','/xxx',{
  success(response){},fail:(request,status)=>{}
})

4.1 改成Promise写法

  • 调用代码
ajax('get','/xxx')
  .then((response)=>{},(request)=>{})
  • 通过 .then 传成功和失败的回调
    1.then:接收两个参数,前者是成功,后者是失败
    2.promise规定:成功和失败回调都只能接收一个参数
    3.如果成功了就拿到response,如果失败了就拿到request
  • ajax('get','/xxx')返回了啥?
    1.之前的 ajax 没有return,所以返回了undefined
    2.现在的 ajax 返回了一个 promise 对象,这个promise对象可以对之前的异步请求添加成功和失败的回调
    ——类似jQuery返回一个 API 对象,这个对象可以操作之前的数据
    3.总结: ajax() 返回了一个含有 .then 的对象
    ——如何返回对象:改源代码

4.2 修改源代码

  • 使其返回一个含有 .then 的对象
  • 在 ajax 函数一进来就 return
    return new Promise((resolve, reject) => { })
    1.new Promise:构造函数,接收的参数是一个函数
    2.这个函数接收两个参数:resolve 和 reject
    3.成功的时候调用:resolve
    失败调用:reject
  • 这样就返回了一个 Promise的对象
ajax = (method, url, options) => {
  return new Promise((resolve, reject) => {
    const { succeess, fail } = options;
    const request = new XMLHttpRequest();
    request.open(method, url);
    request.onreadystatechange = () => {
      if (request.readyState === 4) {
        if (request.status < 400) {
          resolve.call(null, request.response);//this是null
        } else if (request.status >= 400) {
          reject.call(null, request);
        }
      }
    };
    request.send();
  });
};

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

4.3 背下这5个单词

  • return new Promise((resolve,reject)=>{})

5.小结

  • 如何让异步的回调函数变成Promise函数
  • 第一步
  1. return new Promise((resolve,reject)=>{...})
  2. 任务成功则调用 resolve(result)
  3. 任务失败则调用 reject(error)
    上面两个函数都只接受一个参数
  4. resolve和reject会再去调用成功和失败函数
    resolve会调用then后面的第一个函数
    reject会调用then后面的第二个函数
  • 第二步
    使用 .then(success,fail)传入成功和失败函数

6.现在封装的 ajax 的缺点

  • post无法上传数据
    request.send(这里可以上传数据,如用户名)
  • 不能设置请求头
    request.setRequestHeader(key,value)
  • 解决办法:
    1.花时间把 ajax 写到完美
    2.使用 jQuery.ajax jQuery中文文档
    —— jQuery.ajax 非常完美,但现在已经没有人用了
    3.使用 axios (这个库比jQuery逼格高)

axios

  • 目前最新的AJAX库
    React和Vue都是用的这个
  • 抄袭了jQuery的封装思路
  • Axios 作弊表
  • 通过博客快速了解axios的用法

1.axios的高级用法

  • JSON自动处理
    axios如果发现响应的 Content-Type 是json
    就会自动调用 JSON.parse
    正确设置Content-Type是一个好习惯
  • 请求拦截器
    可以在所有请求里加些东西,比如查询参数
  • 响应拦截器
    可以在所有响应里加些东西,甚至改内容
  • 可以生成不同实例(对象)
    不同的实例可以设置不同的配置,用于复杂常见

2.封装!

  • 所有觉得麻烦的代码都封装起来!!!

3.Promise不能取消

  • 但是axios可以取消,因为它自己有一个方式: aixos.CancelToken
  • 但取消的不是promise,而是那个请求

总结

  • 异步:不能直接拿到结果
  • 异步为什么会用到回调?
    为了拿到那个不能拿到的结果
  • 回调的三个问题:回调地狱、名字、错误处理
  • Promise是什么?
    1976年的一种设计模式
  • 如何使用Promise:五个单词
  • 如何使用Axios:BootCDN中搜索axios,然后复制min.js 文件,复制scrpt标签即可
  • Promise是前段解决异步问题的统一方案
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值