ajax.js(来自项目)学习笔记

一、学习资料

1、axios:一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端

 

特点:

从浏览器中创建 XMLHttpRequests

从 node.js 创建 http 请求

支持 Promise API

拦截请求和响应

转换请求数据和响应数据

取消请求

自动转换 JSON 数据

客户端支持防御 XSRF

 

2、qs: node.js的QueryString模块

 

·作用是解析和格式化URL查询字符串,即对http请求所带的数据进行解析和格式化。

·只提供四个方法

1)querystring.parse(str[, separator[, eq[, options]]]) 将一个字符串反序列化为一个对象

  • str <string>要解析的URL查询字符串
  • sep <string>用于在查询字符串中分隔键和值对的子字符串。默认为'&'
  • eq <string>。用于分隔查询字符串中的键和值的子字符串。默认为'='
  • options <对象>
    • o decodeURIComponent <function>在查询字符串中解码百分比编码字符时使用的函数。默认为 querystring.unescape()
    • o maxKeys <number>指定要解析的最大键数。默认为1000。指定0删除键盘计数限制。

querystring.parse()方法将URL查询字符串(str)解析为键值对的集合。

例如,查询字符串'foo=bar&abc=xyz&abc=123'被解析为:

 

 

2)querystring.stringfy(obj[, separator[, eq[, options]]]) 将一个对象序列化为一个字符串

  • obj <Object>要序列化为URL查询字符串的对象
  • sep <string>用于在查询字符串中分隔键和值对的子字符串。默认为'&'
  • eq <string>。用于分隔查询字符串中的键和值的子字符串。默认为'='
  • options
    • o encodeURIComponent <function>在查询字符串中将URL不安全字符转换为百分比编码时使用的函数。默认为 querystring.escape()

querystring.stringify()方法obj通过遍历对象的“自己的属性” 从给定的URL中产生一个URL查询字符串。

例子:

 

 

3)querystring.escape(str) 对传入的字符串进行编码

例子:

 

 

4)querystring.unescape(str) 对可能含有%的字符串进行解码

例子:

 

 

3、Process:node.js的一个模块,提供有关信息,控制当前node.js的进程。事实上是nodejs中的一个全局变量,因此使用的时候无需require()。

Process.env返回一个包含用户环境信息的对象。

 

 

4、axios.create()通过自定义配置新建一个axios的实例。

 

 

1)baseurl:baseurl将自动加在url前面,除非url是一个绝对url。它可以通过设置一个baseurl便于为axios实例的方法传递相对url。

2)timeout:请求超时的毫秒数,如果请求花费超过了timeout的时间,请求将被中断。

3)header:被发送的自定义请求头

·Content-Type代表发送端发送的实体数据的数据类型。

application/x-www-form-urlencoded是最常见的post提交数据的方式,提交的数据按照键值对key1=val1&key2=val2的方式进行编码

·Accept代表发送端(客户端)希望接受的数据类型。

application/json客户端接受服务端json格式的数据。

  · If-Modified-Since

Last-Modified 是由服务器往客户端发送的 HTTP 头,而 If-Modified-Since 则是由客户端往服务器发送的头。再次请求本地存在的 cache 页面时,客户端会通过 If-Modified-Since 将先前服务器端发过来的 Last-Modified 最后修改时间戳发送回去,这是为了让服务器端进行验证,通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回新的内容,如果是最新的,则 返回 304 告诉客户端其本地 cache 的页面是最新的,于是客户端就可以直接从本地加载页面了,这样在网络上传输的数据就会大大减少,同时也减轻了服务器的负担。

 

5、只读函数get:

 

 

axios实例的get方法:axios.get(url[ ,config ])

·url<string> 用于请求的服务器url

·config <obj> 创建请求时的配置选项,可在https://www.kancloud.cn/yunye/axios/234845详细查看

函数里设置创建请求的配置选项,包括params(即将与请求一起发送的url参数)和请求超时的时间。

配置过程:请求时发送的数据不为空,对象params的属性params(params是即将与请求一起发送的url参数)就等于data,timeout不为0,params的属性timeout就等于timeout。

axios的get请求返回的也是一个promise对象,跟踪对象只要后面加一个catch方法就好了。

 

6、 只读函数post:

 

 

axios实例的post方法:axios.post(url[ ,data[ ,config ]])

·url<string> 用于请求的服务器url

·config <obj> 创建请求时的配置选项,可在https://www.kancloud.cn/yunye/axios/234845详细查看

函数里设置post发送的数据和创建请求的配置选项,包括请求超时的时间。

axios的post请求返回的也是一个promise对象,跟踪对象只要后面加一个catch方法。

 

7、 promise的作用与回调方法(callback)一样,都是在某种情况下执行设定好的方法。但promise的多重链式调用能使代码更整洁,避免出现“回调地狱”(回调嵌套太多层)。在es6中,promise成为了原生对象可以直接使用。

Ajax请求的传统写法:   

 

 

改为promise写法:

 

 

很显然,promise的写法把异步调用中使用回调函数的场景改为了.then()、.catch()等函数链式调用的方式,基于promise可以把复杂的异步调用方式进行模块化。

 

Promise的原理分析:

Promise对象共有三个状态,分别是:

·pending(进行中)

·resolved(已完成,又称为fullfilled)

·rejected(已失败)

由异步操作的结果决定当前是什么状态。状态的改变只有两种可能:

·从pending变为fullfilled

·从pending变为rejected

只要这两种情况发生,状态就不会再改变了,因此状态是不能逆向改变的。

构建promise:

 

Promise的构造函数接受一个函数作为参数,该函数的两个参数分别为resolve和reject两个函数。

·Resolve函数将promise对象的状态由pending变为resolved,异步操作成功时调用,并将异步操作的结果,作为参数传递出去。

·reject函数将状态由pending变为rejected,异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

 

  Promise的实例方法:

Promise对象拥有两个实例方法then()和catch()。

·then()方法接受两个函数作为参数,第一个是状态变为resolved时调用,第二个则是状态变为rejected是调用,第二个函数是可选的。

Promise实例生成以后,可以用then方法指定resolved状态和rejected状态的回调函数,即成功和失败的回调函数。

promise构造函数中通常都是异步的,所以then方法往往都先于resolvereject方法执行。这两个函数作为成功和失败的回调函数,都接受promise对象传出的值作为参数。

    

then()方法将返回一个新的promise。

因此then可以链式调用,在新的对象上添加失败或成功的回调。

 

·catch()方法的作用是捕获promise的错误。

与then()方法的rejected回调作业几乎一致。

我们知道,如果 Promise 状态已经变成resolved,再抛出错误是无效的。

 

 

上面代码中,Promise 在resolve语句后面,再抛出错误,不会被捕获,等于没有抛出。因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了。

由于promise对象的错误会一直向后传递,直到被捕获,即错误总会被下一个catch所捕获。then方法指定的回调函数,若抛出错误,也会被下一个catch捕获。catch中也能抛错,则需要后面的catch来捕获。

 

 

一般来说,不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。

这样就能够在下一个catch()中统一处理这些错误。同时catch()也能够捕获then()中抛出的错误,所以建议不使用then()的rejected回调,而是统一使用catch()来处理错误。

跟传统的try/catch代码块不同的是,如果没有使用catch方法指定错误处理的回调函数,Promise 对象抛出的错误不会传递到外层代码,即不会有任何反应。Promise 内部的错误不会影响到 Promise 外部的代码。

 

二、总结

Ajax.js的流程(过程)

1、创建axios的实例

 

const instance = axios.create({

  baseURL: baseUrl,

  timeout: 20000,

  headers: {

    'Content-Type': 'application/x-www-form-urlencoded',

    'Accept': 'application/json',

    'If-Modified-Since': '0'

  }

});

 

2、封装axios实例的get和post方法:

若执行只读函数get()或post():

1)分别发送get请求和post请求

2)用catch捕获错误和处理错误,

3)返回一个新的promise实例。

const get = (url, data, timeout) => {

  let params;

  if (data) {

    params = {

      params: data

    };

  }

  if (timeout) {

    params.timeout = timeout;

  }

 

  return instance

    .get(url, params)

    .catch(handleError);

};

 

const post = (url, data, timeout) => {

  data = qs.stringify(data);

  const config = {

    timeout

  };

  return instance

    .post(url, data, config)

    .catch(handleError);

};

 

3、封装get和post的接口:

若执行getAPI()或者postAPI(),会返回一个promise实例,生成该promise实例的构造函数做了除了返回一个新的promise实例以外的以下几件事情:

1)分别执行了封装好的get()方法和post()方法

2)利用promise的then()方法指定了get()或者post()成功以后调用的回调函数resolve(response.data)

const getApi = (url, data, timeout) => {

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

    get(url, data, timeout)

      .then(response => {

        resolve(response.data);

      });

  });

};

 

const postApi = (url, data, timeout) => {

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

    post(url, data, timeout)

      .then(response => {

        resolve(response.data);

      });

  });

};

 

 

三、参考文档

ECMAScript 6 入门

http://es6.ruanyifeng.com/#docs/promise#%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95

初探promise

https://segmentfault.com/a/1190000007032448

Axios 中文说明

https://www.kancloud.cn/yunye/axios/234845

Node.js v9.40文档

https://nodejs.org/api/querystring.html

posted @ 2018-01-23 10:31  zi_chil  阅读(202)  评论(0编辑  收藏  举报